답변:
앞으로 typedef를 수행 할 수 있습니다. 그러나 할
typedef A B;
먼저 선언해야합니다 A
:
class A;
typedef A B;
typedef
, 순방향 선언을 사용하여 복잡한 다중 레벨 템플리트 유형 의 이름을 지정하는 경우 다소 복잡하고 어렵습니다. 말할 것도없이 기본 템플릿 인수에 숨겨진 구현 세부 정보를 살펴볼 필요가 있습니다. 그리고 최종 솔루션은 길고 읽을 수없는 코드입니다 (특히 유형이 다양한 네임 스페이스에서 온 경우)는 원래 유형으로 변경되기 쉽습니다.
나와 같은 당신을 위해, 일부 C ++ 코드에서 typedef를 사용하여 정의 된 C 스타일 구조체를 선언하려고하는 사람들은 다음과 같은 해결책을 찾았습니다 ...
// a.h
typedef struct _bah {
int a;
int b;
} bah;
// b.h
struct _bah;
typedef _bah bah;
class foo {
foo(bah * b);
foo(bah b);
bah * mBah;
};
// b.cpp
#include "b.h"
#include "a.h"
foo::foo(bah * b) {
mBah = b;
}
foo::foo(bah b) {
mBah = &b;
}
"fwd typedef 선언"을하려면 클래스 또는 구조체를 fwd 선언 한 다음 typedef 선언 된 유형을 사용할 수 있습니다. 컴파일러는 여러 개의 동일한 typedef를 사용할 수 있습니다.
긴 형식 :
class MyClass;
typedef MyClass myclass_t;
짧은 형식:
typedef class MyClass myclass_t;
C ++ (일반 C는 아님)에서 두 정의가 완전히 동일 하다면 유형을 두 번 typedef하는 것이 합법적입니다 .
// foo.h
struct A{};
typedef A *PA;
// bar.h
struct A; // forward declare A
typedef A *PA;
void func(PA x);
// baz.cc
#include "bar.h"
#include "foo.h"
// We've now included the definition for PA twice, but it's ok since they're the same
...
A x;
func(&x);
A
있기 때문에 어떻게 이런 식으로 필드를 A
정의합니까?
유형을 선언하기 때문에 크기를 알아야합니다. 형식에 대한 포인터를 전달하거나 형식에 대한 포인터를 typedef로 전달할 수 있습니다.
정말로 원한다면 pimpl 관용구를 사용하여 포함을 낮출 수 있습니다. 그러나 포인터가 아닌 형식을 사용하려면 컴파일러에서 크기를 알아야합니다.
편집 : j_random_hacker는이 답변에 중요한 자격을 추가합니다. 기본적으로 크기를 사용 하여 유형 을 사용해야 한다는 것을 알아야하지만 형식 이 존재 한다는 것을 알아야 할 경우 앞으로 선언을 할 수 있습니다 . 유형. OP는 코드를 표시하지 않았지만 컴파일하지 않을 것이라고 불평했기 때문에 OP가 유형을 참조 하려고하는 것이 아니라 유형 을 사용 하려고한다고 가정 했습니다.
앞으로 선언을 사용 하는 대신 전체의 #include
의하면 경우에만 수 없습니다 (이 파일의 범위) 유형 자체 만의 포인터 또는 참조를 사용하여 의도.
형식 자체를 사용하려면 컴파일러에서 크기를 알아야합니다. 따라서 전체 선언을보아야 #include
합니다. 따라서 전체 가 필요합니다.
그러나 포인터 또는 참조의 크기는 포인트의 크기에 관계없이 컴파일러에 알려져 있으므로 정방향 선언으로 충분합니다. 형식 식별자 이름을 선언합니다.
흥미롭게도 포인터, 참조 class
또는 struct
유형을 사용할 때 컴파일러는 불완전한 유형을 처리 하여 포인트 유형을 전달할 필요가 없습니다.
// header.h
// Look Ma! No forward declarations!
typedef class A* APtr; // class A is an incomplete type - no fwd. decl. anywhere
typedef class A& ARef;
typedef struct B* BPtr; // struct B is an incomplete type - no fwd. decl. anywhere
typedef struct B& BRef;
// Using the name without the class/struct specifier requires fwd. decl. the type itself.
class C; // fwd. decl. type
typedef C* CPtr; // no class/struct specifier
typedef C& CRef; // no class/struct specifier
struct D; // fwd. decl. type
typedef D* DPtr; // no class/struct specifier
typedef D& DRef; // no class/struct specifier
나는 같은 문제가 있었고 다른 파일의 여러 typedef를 엉망으로 만들고 싶지 않았으므로 상속으로 해결했습니다.
였다:
class BurstBoss {
public:
typedef std::pair<Ogre::ParticleSystem*, bool> ParticleSystem; // removed this with...
했다 :
class ParticleSystem : public std::pair<Ogre::ParticleSystem*, bool>
{
public:
ParticleSystem(Ogre::ParticleSystem* system, bool enabled) : std::pair<Ogre::ParticleSystem*, bool>(system, enabled) {
};
};
매력처럼 일했다. 물론, 나는 모든 참조를 변경해야했다.
BurstBoss::ParticleSystem
단순히
ParticleSystem
나는 대체 typedef
( using
상속과 생성자 상속 될 특정)을 (?).
실물
using CallStack = std::array<StackFrame, MAX_CALLSTACK_DEPTH>;
대체
struct CallStack // Not a typedef to allow forward declaration.
: public std::array<StackFrame, MAX_CALLSTACK_DEPTH>
{
typedef std::array<StackFrame, MAX_CALLSTACK_DEPTH> Base;
using Base::Base;
};
이렇게하면 CallStack
다음과 같이 선언 할 수있었습니다 .
class CallStack;
Bill Kotsias가 지적했듯이 포인트의 typedef 세부 정보를 비공개로 유지하고 앞으로 선언하는 유일한 합리적인 방법은 상속입니다. C ++ 11로 조금 더 멋지게 할 수 있습니다. 이걸 고려하세요:
// LibraryPublicHeader.h
class Implementation;
class Library
{
...
private:
Implementation* impl;
};
// LibraryPrivateImplementation.cpp
// This annoyingly does not work:
//
// typedef std::shared_ptr<Foo> Implementation;
// However this does, and is almost as good.
class Implementation : public std::shared_ptr<Foo>
{
public:
// C++11 allows us to easily copy all the constructors.
using shared_ptr::shared_ptr;
};
@ BillKotsias와 마찬가지로 상속을 사용했으며 저에게 효과적이었습니다.
나는이 혼란을 바꿨다 (내 선언에 모든 부스트 헤더가 필요하다 * .h)
#include <boost/accumulators/accumulators.hpp>
#include <boost/accumulators/statistics.hpp>
#include <boost/accumulators/statistics/stats.hpp>
#include <boost/accumulators/statistics/mean.hpp>
#include <boost/accumulators/statistics/moment.hpp>
#include <boost/accumulators/statistics/min.hpp>
#include <boost/accumulators/statistics/max.hpp>
typedef boost::accumulators::accumulator_set<float,
boost::accumulators::features<
boost::accumulators::tag::median,
boost::accumulators::tag::mean,
boost::accumulators::tag::min,
boost::accumulators::tag::max
>> VanillaAccumulator_t ;
std::unique_ptr<VanillaAccumulator_t> acc;
이 선언에 (* .h)
class VanillaAccumulator;
std::unique_ptr<VanillaAccumulator> acc;
구현 (* .cpp)은
#include <boost/accumulators/accumulators.hpp>
#include <boost/accumulators/statistics.hpp>
#include <boost/accumulators/statistics/stats.hpp>
#include <boost/accumulators/statistics/mean.hpp>
#include <boost/accumulators/statistics/moment.hpp>
#include <boost/accumulators/statistics/min.hpp>
#include <boost/accumulators/statistics/max.hpp>
class VanillaAccumulator : public
boost::accumulators::accumulator_set<float,
boost::accumulators::features<
boost::accumulators::tag::median,
boost::accumulators::tag::mean,
boost::accumulators::tag::min,
boost::accumulators::tag::max
>>
{
};