AFAIK,封闭类数据成员在嵌套类中也是可见的。
struct A { struct B { int arr[n]; // how come n is not visible here, but it is visible in next statement. int x = n; }; static const int n = 5; };
see live demo here
4zcjmb1e1#
为什么n在这里不可见,但在下一个语句中却可见。因为int x = n;是一个完整的类上下文,而int arr[n];不是。这可以从class.mem中理解,它声明:
int x = n;
int arr[n];
6)类的完整类上下文是:**6.4)**默认成员初始值设定项
在类的成员规范内。[注意:如果巢状类别是在封入类别的成员规格内定义,则巢状类别的完整类别内容也是任何封入类别的完整类别内容。-注意结束]
**7)**类在类说明符的结尾}处被认为是完全定义的对象类型([basic.types])(或完全类型)。类在其完全类上下文中被认为是完全的;否则它被认为在它自己的类成员规范内是不完整的。
(强调我)请注意,int arr[n];中的n是数组类型的一部分,但上面引用的语句不允许n用作非静态数据成员类型的一部分,因此出现错误。出于同样的原因,如果我们编写以下语句,也会出现同样的错误:
n
struct A { struct B { int x = n; //----------------------v--------->same error as before std::array<int, n> arr; }; static constexpr int n = 5; };
zxlwwiss2#
我的回答更像是对为什么会这样的直觉:在int arr[n]中,n用于定义字段,而在int x = n中,n用于初始化字段,类似于B() : x(n) {}。请考虑以下示例:
int arr[n]
int x = n
B() : x(n) {}
struct A { struct B { int arr[n]; int x = n; }; static constexpr int n = offsetof(B, x); };
这里n的值依赖于arr的大小,arr的大小依赖于n,这是一种交叉依赖,因此struct没有很好地定义。如果C++的规则是让你的用例是法律的的,那么这也应该是合法的,这是不可能的。但是,它仍然允许我们在初始化中使用offsetof,因为为什么不呢?
arr
struct
offsetof
ecbunoof3#
关于评价变量的东西在左手边赋值,不是计算机语言Maven,下面的工作。
#include <iostream> using namespace std; struct A { struct B { int *arr = new int[n](); int x = n; }; static const int n = 5; }; int main() { cout << "Hello World!"; return 0; }
3条答案
按热度按时间4zcjmb1e1#
为什么n在这里不可见,但在下一个语句中却可见。
因为
int x = n;
是一个完整的类上下文,而int arr[n];
不是。这可以从class.mem中理解,它声明:6)类的完整类上下文是:
**6.4)**默认成员初始值设定项
在类的成员规范内。[注意:如果巢状类别是在封入类别的成员规格内定义,则巢状类别的完整类别内容也是任何封入类别的完整类别内容。-注意结束]
**7)**类在类说明符的结尾}处被认为是完全定义的对象类型([basic.types])(或完全类型)。类在其完全类上下文中被认为是完全的;否则它被认为在它自己的类成员规范内是不完整的。
(强调我)
请注意,
int arr[n];
中的n
是数组类型的一部分,但上面引用的语句不允许n
用作非静态数据成员类型的一部分,因此出现错误。出于同样的原因,如果我们编写以下语句,也会出现同样的错误:zxlwwiss2#
我的回答更像是对为什么会这样的直觉:
在
int arr[n]
中,n用于定义字段,而在int x = n
中,n用于初始化字段,类似于B() : x(n) {}
。请考虑以下示例:
这里
n
的值依赖于arr
的大小,arr的大小依赖于n
,这是一种交叉依赖,因此struct
没有很好地定义。如果C++的规则是让你的用例是法律的的,那么这也应该是合法的,这是不可能的。但是,它仍然允许我们在初始化中使用
offsetof
,因为为什么不呢?ecbunoof3#
关于评价变量的东西在左手边赋值,不是计算机语言Maven,下面的工作。