使用私有嵌套类型作为参数

时间:2016-05-06 22:28:01

标签: c++

我遇到了这个奇怪的问题,我不知道为什么会这样。编译以下第一个和第二个代码片段,而第三个不编译:

编译:

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 {};
};

是什么让第三个无法编译而第一个可以?

2 个答案:

答案 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}}之类的内容无法访问。