如果前向声明不够,如何避免"'标识符'使用未定义的类/结构/联合'名称'"错误?

Dmi*_*yov 8 c++

根据http://msdn.microsoft.com/en-us/library/9ekhdcxs(v=vs.80).aspx,

如果您尝试在其前向声明仅在范围内的类型的堆栈上声明对象,也会发生C2079.

class A;

class B {
    A a;   // C2079
};

class A {};
Run Code Online (Sandbox Code Playgroud)

可能的决议:

class A;

class C {};

class B {
   A * a;
   C c;
};
class A {};
Run Code Online (Sandbox Code Playgroud)

我的问题是当我遇到以下情况时如何消除此错误:

class A;  // Object

class B   // Container
{
   public:
     typedef int SomeTypedef;
   private:
     A a;   // C2079
};

class A {
   void Foo(B::SomeTypedef);
};
Run Code Online (Sandbox Code Playgroud)

在声明B之前我无法声明A,因为A需要使用B的typedef,并且由于此错误,我无法在A之前声明B.

一种可能的解决方案是使用指向A而不是堆栈变量的指针,但我不想要指针(在这种情况下).

另一个解决方案是不使用typedef,或者不将它放在B类中.但是如果它属于B并且我不想污染我的项目的命名空间,如B :: SomeTypedef是一个比SomeTypedef更合适的名称呢?

Pub*_*bby 3

你的设计是有问题的,尽管嵌套类可能是你想要的:

class B {
   public:
     typedef int SomeTypedef;
   private:
     class A {
       void Foo(SomeTypedef);
     };
     A a;
};
Run Code Online (Sandbox Code Playgroud)

如果没有,也可以使用 CRTP 代码中常见的另一个类来解决。

template<typename T>
struct foo;

class A;
class B;

template<>
struct foo<B> {
  typedef int SomeTypedef;
};

class A {
   void Foo(foo<B>::SomeTypedef);
};

class B : foo<B> {
   private:
     A a;
};
Run Code Online (Sandbox Code Playgroud)

或者您可以使用另一个名称空间。

  • 您所需要的只是一个基类,模板没有添加任何内容。 (2认同)