为什么编译器不让我向前声明类型定义?
假设这是不可能的,那么保持我的包含树小的最佳实践是什么?
为什么编译器不让我向前声明类型定义?
假设这是不可能的,那么保持我的包含树小的最佳实践是什么?
当前回答
在c++(而不是普通C)中,对一个类型定义两次是完全合法的,只要两个定义完全相同:
// 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);
其他回答
我用继承和构造函数继承(?)替换了typedef(用来指定)。
原始
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;
因为要声明一个类型,就需要知道它的大小。可以前向声明指向该类型的指针,也可以对指向该类型的指针进行类型定义。
如果您真的想这样做,您可以使用pimpl习语来减少包含。但是如果你想使用类型,而不是指针,编译器必须知道它的大小。
Edit: j_random_hacker为这个答案添加了一个重要的限定条件,基本上是需要知道该类型的大小才能使用该类型,但是如果我们只需要知道该类型的存在,就可以进行前向声明,以便创建指向该类型的指针或引用。由于OP没有显示代码,但抱怨它不会编译,我假设(可能是正确的)OP试图使用类型,而不仅仅是引用它。
对于那些像我一样,希望在一些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;
}
我也有同样的问题,不想在不同的文件中混淆多个typedef,所以我用继承解决了它:
was:
class BurstBoss {
public:
typedef std::pair<Ogre::ParticleSystem*, bool> ParticleSystem; // removed this with...
did:
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 A B;
你必须先向前申报A:
class A;
typedef A B;