4

我不明白标准中的 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() 的范围和全局范围内查找!

4

2 回答 2

0

为了扩展@JerryCoffin 的评论,合格查找的规则是:

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

3 在 declarator-id 是 qualiified-id 的声明中,在声明的 qualiified-id 之前使用的名称在定义的命名空间范围内查找;qualified-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
}

活生生的例子

于 2014-06-29T15:14:24.300 回答
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 说明符,则查找前面的名称::仅考虑名称空间、类型和特化为类型的模板。如果找到的名称没有指定命名空间或类、枚举或依赖类型,则程序是非良构的。

于 2015-06-18T09:19:40.923 回答