我不太了解标准中的3.4 / 2

时间:2014-06-28 19:54:00

标签: 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::i的范围内没有查找限定名N::i,即它没有在main()范围和全局范围内查找!

2 个答案:

答案 0 :(得分:0)

要扩展@JerryCoffin的评论,限定查找的规则是:

3.4.3 Quali fi ed name lookup [basic.lookup.qual]

  

3在声明者id是quali-ed-id的声明中,名称   在被声明的quali fi ed-id被查询之前使用   定义命名空间范围;查找quali fi ed-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
}

Live Example

答案 1 :(得分:0)

首先查找::的左侧,然后在其中查找右侧。因此,要查找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
}

http://coliru.stacked-crooked.com/a/9a7c9e34b1e74ce7

见§3.4.3/ 1:

  

::范围解析运算符(5.1)应用于表示其类,命名空间或枚举的嵌套名称说明符之后,可以引用类或命名空间成员或枚举数的名称。如果嵌套名称说明符中的::作用域解析运算符前面没有decltype-specifier,则查找::之前的名称仅考虑其专门化为类型的名称空间,类型和模板。如果找到的名称未指定名称空间或类,枚举或依赖类型,则程序格式不正确。