考虑以下代码片段:
class A
{
int b[A::a]; //1, error
void foo(){ int b = A::a; } //2, ok
static const int a = 5;
}
条款 3.4.3.1/1(限定名称查找,类成员)说:
If the nested-name-specifier of a qualified-id nominates a class, the name specified after the nested-name-specifier is looked up in the scope of the class (10.2)
这意味着将查找 //1
和 //2
中嵌套名称说明符之后的名称 a
在类范围内。
条款 10.2(成员名称查找)说:
10.2/2
The following steps define the result of name lookup for a member name f in a class scope C.
10.2/3
The lookup set for f in C, called S(f, C)...
S(f, C) is calculated as follows:
10.2/4
If C contains a declaration of the name f, the declaration set contains every declaration of f declared in C that satisfies the requirements of the language construct in which the lookup occurs.
我不清楚以下内容:
从我引用的引语中可以看出,//1
和 //2
应应用相同的成员查找规则。 但实际上是不同的。为什么我的推理是错误的?
注意:我知道类范围内的非限定名称查找规则。我理解以下代码片段中的行为:
class A
{
int b[a]; //error
void foo(){ int b = a; } //ok
static const int a = 5;
}
这是因为 3.4.1/7 和 3.4.1/8 节(非限定名称查找)中描述的行为。
最佳答案
错误是因为在处理int b[A::a];
时,A
还没有符号a
.在那个编译点,A
仍然不完整,因为我们还没有到达类定义的结束 }
。编译器不会“提前”查看源代码的 future 行是否包含 a
的定义。
你可以通过颠倒行的顺序来看到这一点:
class A
{
static const int a = 5;
int b[A::a]; // OK
};
函数定义没有同样的问题,因为内联函数体直到类定义编译之后才被编译。 (抱歉,我没有方便的标准引用资料)
关于c++ - 类成员限定名称查找,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24299963/