Qua*_*lus 61 c++ scope language-lawyer
我有一个A类,它有两个静态变量.我想用另一个不相关的静态变量初始化一个,就像这样:
#include <iostream>
class A
{
public:
static int a;
static int b;
};
int A::a = 200;
int a = 100;
int A::b = a;
int main(int argc, char* argv[])
{
std::cout << A::b << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出是200.所以,谁能告诉我为什么?
Sto*_*ica 36
根据查找规则,这是正确的.[basic.lookup.unqual]/13说:
查找在类X的静态数据成员的定义中使用的名称(在静态成员的qualified-id之后),就好像该名称是在X的成员函数中使用一样.[注意:[class.static.data] ]进一步描述了静态数据成员定义中名称使用的限制. - 结束说明]
由于不合格a被查找,就好像你在成员函数中一样,它必须首先找到成员A::a.初始化顺序A::a和A::b不影响查找,但它会影响结果的定义.
Jos*_* D. 16
那么,谁能告诉我为什么?
这在basic.scope.class/4中明确说明,强调我的:
扩展到或超过类定义结尾的声明的潜在范围也扩展到由其成员定义定义的区域,即使成员是在类之外的词法上定义的(这包括静态数据成员定义,嵌套类定义,和成员函数定义,包括成员函数体和此类定义的声明器部分的任何部分,它们遵循declarator-id,包括parameter-declaration-clause和任何默认参数).
因此,当你有
int A::a = 200;
int a = 100;
int A::b = a; // note the '::' scope resolution operator
// OUTPUT: 200
Run Code Online (Sandbox Code Playgroud)
a实际上是A::a因为类范围被扩展了A::b.
不像你有:
int A::a = 200;
int a = 100;
int b = a; // note b is not A::b
// i.e. without the '::', scope resolution operator
// OUTPUT: 100
Run Code Online (Sandbox Code Playgroud)
a会引用(全局),::a因为b这里不是成员class A,
即没有类范围扩展.
如果在成员的declarator-id之后的静态成员的定义中使用了unqualified-id,并且名称查找([basic.lookup.unqual])发现unqualified-id引用静态成员,枚举器或嵌套类型在成员类(或成员类的基类)中,将unqualified-id转换为qualified-id表达式,其中nested-name-specifier命名引用该成员的类作用域.[注意:有关使用非静态数据成员和非静态成员函数的限制,请参见[expr.prim.id]. - 结束说明]
它表示在您的情况下,unqualified-id会转换为qualified-id表达式.
int A::b = a;
Run Code Online (Sandbox Code Playgroud)
您可以设置qualified-id但没有像这样的嵌套名称说明符.
int A::b = ::a;
Run Code Online (Sandbox Code Playgroud)
因为名称查找解析了aas A::a.如果要执行此操作,则需要手动解决范围:
int A::b = ::a;
// ^ Global scope resolution
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2354 次 |
| 最近记录: |