下面的代码无法编译.也许是因为带有std = c ++ 2a的GCC仍然没有与最新的草案完全一致

Wal*_*ldB 0 c++ language-lawyer c++20

[class.mem]/6:

一个完整的类的上下文是一个

(6.1)函数体,(6.2)默认参数,(6.3) noexcept-specifier([except.spec]),(6.4)合同条件,或(6.5)默认成员初始化程序

在类的成员规范内.[注意:如果嵌套类在封闭类的成员规范中定义,则嵌套类的完整类上下文也是任何封闭类的完整类上下文. - 结束说明]

该段落在草案中引入了拉动请求#2231.

据我所知,根据上面的注释,下面的代码应该编译.但事实并非如此.我假设GCC编译器仍然不是最新的草案.我是否正确,或者我对此笔记的理解是否正确?

struct A {
    int i = 1;
    struct B { 
        int j = 2;
        int f() {
            return i + j;
        }
    };
};
Run Code Online (Sandbox Code Playgroud)

哪个失败了:

source>: In member function 'int A::B::f()':
<source>:6:20: error: invalid use of non-static data member 'A::i'
    6 |             return i + j;
      |                    ^
<source>:2:9: note: declared here
    2 |     int i = 1;
      |         ^
Run Code Online (Sandbox Code Playgroud)

Bar*_*rry 7

我认为混淆源于完整类上下文的意义以及如何使用它.

重要的是,名称查找将在i那里找到.所以我可以这样写:

struct A {
    struct B { 
        int j = 2;
        int f() {
            using T = decltype(i); // ok, even though 'i' declared later lexically
            return T{} + j;        // ok
        }
    };
    int i = 1;
};
Run Code Online (Sandbox Code Playgroud)

以及:

struct A {
    struct B { 
        int j = 2;
        int f() {
            return i + j; // ok, even though 'i' declared later lexically
        }
    };
    static const int i = 1;
};
Run Code Online (Sandbox Code Playgroud)

实际上,这在C++ 11中一直很好.

i仍然是非静态成员,因此您只能从类型对象的上下文中访问它A.在成员函数体内B,我们不隐含有一个A对象.所以这种免费使用i仍然是不正确的.


那说,这个:

我假设GCC编译器仍然不是最新的草案.

确实如此,并且在相当长的一段时间内仍将如此.