我本来打算针对 GCC 提交一个错误,但后来意识到,如果我对标准的解释是正确的,那么这是一个核心语言缺陷,而不是编译器错误。
当数组类型的静态数据成员在类作用域之外定义时,将在类作用域中查找数组绑定中的标识符。
§9.4.2 [class.static.data] 说“静态数据成员定义中的初始值设定项表达式位于其类的范围内 (3.3.7)”,但没有提及声明符本身。这似乎是声明器中唯一的名称查找上下文。
§8.4.2 [dcl.array] 没有提到数组绑定的范围,因此默认情况下表达式在封闭范围(即命名空间)中计算。
class X {
static int const size = some_complicated_metafunction<>::value;
static int arr[ size ];
};
// "size" should be qualified as "X::size", which is an access violation.
int X::arr[ size ] = {};
问题是,如果数组边界不在类作用域中求值,则无法访问私有类成员,并且some_complicated_metafunction<>
必须重新指定。数组绑定需要与初始值设定项相同的范围,其原因与初始值设定项基本相同。 (虽然不是那么强大,因为常量表达式总是可以重新计算,这与私有对象的地址不同。)
我是否遗漏了什么或者 DR 是否合适?
我认为成员定义中绑定的数组位于类范围内。标准3.3.7/1:
以下规则描述了类中声明的名称的范围。
...
5) 延伸到或超过类定义末尾的声明的潜在范围也延伸到由其成员定义定义的区域,即使成员是在类外部按词法定义的(这包括静态数据成员定义、嵌套类)定义、成员函数定义(包括成员函数体和此类定义的声明符部分的任何部分)遵循声明符 id,包括参数声明子句和任何默认参数(8.3.6)。 ...
这里的声明者 ID 是X::arr
.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)