我遇到了这个奇怪的问题,我不知道为什么会这样。编译以下第一个和第二个代码片段,而第三个不编译:
编译:
class Foo {
public:
Foo() { Bar(); }
private:
class Bar {};
};
编译:
class Foo {
class Bar {}; // Or only forward declare here and define later
public:
Foo(Bar) {}
}
不编译:
class Foo {
public:
Foo(Bar) {}
private:
class Bar {};
};
是什么让第三个无法编译而第一个可以?
答案 0 :(得分:4)
通常,在C ++中,您只能引用先前在翻译单元中进行的声明。但是,在类定义中,允许成员函数的定义引用稍后在类中生成的声明。基本上,编译器重新构造您的类内定义,以便它们像在类之后编写一样工作。
但这只适用于函数定义。函数的声明(包括参数类型)不允许这样做。它们只能引用已按文件顺序进行的声明。
所以你可以这样做:
class Test
{
public:
void Func(int x) {Inner foo;}
private:
class Inner {};
};
但不是这样:
class Test
{
public:
void Func(Inner x) {}
private:
class Inner {};
};
答案 1 :(得分:2)
第一个示例没有向外部公开Foo
的任何内容,而第三个示例。
第三个例子就是说,存在一些类Bar
,其构造函数具有类型为Bar
的单个参数。但Foo f{Foo::Bar{}};
是外界所不知道的。想象一下,调用这样的构造函数。
Foo::Bar
可能导致{{1}}之类的内容无法访问。