Wal*_*ldB 0 c++ language-lawyer c++20
一个完整的类的上下文是一个
(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)
我认为混淆源于完整类上下文的意义以及如何使用它.
重要的是,名称查找将在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编译器仍然不是最新的草案.
确实如此,并且在相当长的一段时间内仍将如此.