我有一个具有两个静态变量的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;
}
输出为200。那么,有人可以告诉我为什么吗?
答案 0 :(得分:36)
根据查找规则,这是正确的。 [basic.lookup.unqual]/13说:
在类X的静态数据成员的定义中使用的名称 (在静态成员的qualified-id之后)查找,就像 名称在X的成员函数中使用。[注:[class.static.data] 进一步描述了名称中使用名称的限制 静态数据成员的定义。 —尾注]
由于查找不合格的a
就像您在成员函数中一样,因此必须首先找到成员A::a
。 A::a
和A::b
的初始化顺序虽然会影响结果的定义程度,但不会影响查找。
答案 1 :(得分:16)
那么,谁能告诉我为什么?
basic.scope.class/4中对此进行了明确说明,重点是:
延伸到末尾或超出末尾的声明的潜在范围 类定义的扩展到由其定义的区域 成员定义,即使成员在词汇表外部定义 类(此包括静态数据成员定义,嵌套类 定义和成员函数定义,包括成员 函数体以及此类的声明器部分的任何部分 声明符编号之后的定义,包括 参数声明子句和任何默认参数)。
因此,当您拥有
int A::a = 200;
int a = 100;
int A::b = a; // note the '::' scope resolution operator
// OUTPUT: 200
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
a
指的是(全局)::a
,因为此处的b
不是class A
的成员,
即没有类范围扩展。
答案 2 :(得分:8)
如果在静态成员的定义中使用了unqualified-id,则该成员的声明者ID 之后,和名称查找([basic.lookup.unqual])会发现该不合格ID -id是成员类(或成员类的基类)的静态成员,枚举器或嵌套类型,未限定ID会转换为限定ID表达式,其中nested-name-specifier命名引用成员的类范围。 [注意:有关使用非静态数据成员和非静态成员函数的限制,请参见[expr.prim.id]。 —尾注]
它表示在您遇到的情况下,unqualified-id会转换为qualified-id表达式。
int A::b = a;
您可以设置qualified-id,但没有这样的嵌套名称说明符。
int A::b = ::a;
答案 3 :(得分:6)