在C ++中提前声明typedef

为什么编译器不让我转发声明typedef?

假设这是不可能的,那么让我们的包含树保持小的最佳做法是什么?

你可以做正向typedef。 但要做

typedef AB; 

你必须先提出申报A

 class A; typedef AB; 

对于那些喜欢我的人来说,在一些c ++代码中,我正在寻找一个正在声明一个使用typedef定义的C风格的结构,我发现了一个如下的解决scheme:

 // ah typedef struct _bah { int a; int b; } bah; // bh struct _bah; typedef _bah bah; class foo { foo(bah * b); foo(bah b); bah * mBah; }; // b.cpp #include "bh" #include "ah" foo::foo(bah * b) { mBah = b; } foo::foo(bah b) { mBah = &b; } 

在C ++中(但不是普通的C),只要两种定义完全相同,那么键入一个types两次是完全合法的:

 // 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); 

因为要声明一个types,所以它的大小需要知道。 你可以转发声明指向types的指针,或者typedef指向types的指针。

如果你真的想要的话,你可以使用pimpl成语来保持包含。 但是如果你想使用types而不是指针,编译器必须知道它的大小。

编辑:j_random_hacker增加了一个重要的资格,这个答案,基本上,大小需要知道使用的types,但一个前向声明,如果我们只需要知道types存在 ,以创build指针或引用types。 由于OP没有显示代码,但抱怨它不会编译,我假设(可能是正确的)OP正在尝试使用该types,而不仅仅是引用它。

要“fwd声明一个typedef”你需要fwd声明一个类或一个结构,然后你可以typedef声明的types。 编译器可以接受多个相同的typedef。

长表:

 class MyClass; typedef MyClass myclass_t; 

简写:

 typedef class MyClass myclass_t; 

只有当你打算使用types本身(在这个文件的作用域中),而是一个指针或对它的引用时,使用前向声明而不是完整的#include才是可能的。

要使用types本身,编译器必须知道它的大小 – 因此必须看到它的完整声明 – 因此需要一个完整的#include

但是,无论指针的大小如何,指针或引用的大小都是编译器已知的,所以前向声明就足够了 – 它声明了一个types标识符名称。

有趣的是,当使用指针或引用classstructtypes时,编译器可以处理不完整的types,从而保存您需要转发的指针types:

 // 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,所以我解决了它的inheritance:

是:

 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 

正如Bill Kotsias所指出的那样,唯一合理的方法就是保持你的点的typedef细节是私有的,并且向前宣布它们是inheritance的。 虽然你可以用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; };