C++ 我不知道';我不理解标准中的3.4/2

C++ 我不知道';我不理解标准中的3.4/2,c++,c++11,language-lawyer,name-lookup,qualified-name,C++,C++11,Language Lawyer,Name Lookup,Qualified Name,我不理解标准中的3.4/2: 名称“在表达式的上下文中查找”作为 找到表达式的作用域中的非限定名称 如果名称是限定的,如下面的N::i,该怎么办 #include <iostream> namespace N { int i = 1; } int main() { int i = 0; std::cout << N::i << '\n'; } #包括 命名空间N{int i=1;} int main() { int i=0; std::

我不理解标准中的3.4/2:

名称“在表达式的上下文中查找”作为 找到表达式的作用域中的非限定名称

如果名称是限定的,如下面的
N::i
,该怎么办

#include <iostream>

namespace N { int i = 1; }

int main()
{
    int i = 0;

    std::cout << N::i << '\n';
}
#包括
命名空间N{int i=1;}
int main()
{
int i=0;

std::cout要扩展@JerryCoffin的注释,限定查找的规则如下:

3.4.3限定名称查找[basic.lookup.qual]

3在声明人id为限定id的声明中,名称 在声明的合格id在 定义名称空间范围;查找合格id后面的名称 在成员的类或命名空间的范围内

下面是一个例子:

#include <iostream>

struct N { enum { i = 1 }; };

int main()
{
    std::cout << N::i << '\n'; // prints 1

    struct N { enum { i = 0 }; };

    std::cout << N::i << '\n'; // prints 0
}
#包括
结构N{enum{i=1};};
int main()
{

std::cout首先查找
的左侧,然后在其内部查找右侧。因此,要查找
N::i
,首先使用非限定查找查找
N
,然后在
N
内部查找
i
。简单

在您的示例中,您在本地重新定义了
N
。在本地定义之后,根据§3.3.10隐藏外部定义:“可以通过嵌套声明性区域或派生类中相同名称的显式声明隐藏名称。”

由于编译器从一开始就知道左侧(
N
)必须生成类型、命名空间或枚举,因此忽略任何其他查找结果(即函数、变量和模板)。因此,您还可以执行以下操作:

#include <iostream>

struct N { enum { i = 1 }; };

int main()
{
    int N = 3;
    std::cout << N::i << '\n'; // prints 1
    std::cout << N << '\n'; // prints 3

    struct N { enum { i = 0 }; };

    std::cout << N::i << '\n'; // prints 0
}
#包括
结构N{enum{i=1};};
int main()
{
int N=3;

std::cout 3.4/2是“在表达式上下文中查找”的定义。它不要求在表达式上下文中查找所有名称。“在表达式上下文中查找”是一种查找机制;其他查找机制是限定查找和ADL。由于名称是限定的,因此根据[basic.lookup.qual](§3.4.3)中的规则进行查找。那里没有限定id的声明。该规则实现了成员函数声明如何声明成员类型的参数,而无需对每个参数重复限定。