如何确定参考的背景

时间:2014-06-20 13:51:17

标签: c++ reference namespaces

我正在努力理解N3797 c ++ 14最终工作草案第3.4.3.2/3节的规则:

  

给定X :: m(其中X是用户声明的命名空间),或给定:: m(其中   如果S(X,m)是空集,程序,则X是全局名称空间   是不正确的。否则,如果S(X,m)只有一个成员,或者如果是   引用的上下文是using-declaration(7.3.3),S(X,m)是   m的必要声明集。否则,如果使用m是   不允许从S(X,m)中选择唯一的声明,   该计划格式不正确。

我写了以下代码:

inline namespace A
{
    int i = 42;
};

namespace B 
{
    static const int i = 5;
};

using B::i;

int g= ::i //S(X, i)={using B::i, A::i}

int main() { }

正如上面引用的引文所述,我们有:

  

[...]如果S(X,m)是空集[...]

S(X,m)不为空,进一步:

  

否则,如果S(X,m)只有一个成员

不是真的,更进一步:

  

或者如果引用的上下文是using-declaration

我不明白该约束是如何检查我的示例的。我想了解确定的参考语境如何取决于该参考文献的使用?

1 个答案:

答案 0 :(得分:0)

这一切都很简单,虽然是以令人困惑的方式写的。名称是名称空间的成员或其内联名称空间,或者名称是由某个其他名称空间的using指令引入的名称。如果这样的名称恰好是一个名称,那么它将被使用。

在您的代码示例中,S(global,i)有两个成员,一个是在内联命名空间A中定义的,另一个是使用声明引入的。所以存在歧义。

因此,考虑名称空间的顺序如下。 首先考虑名称空间本身及其内联名称空间。如果名称恰好是一个,则使用它。

Otherewise编译器考虑使用指令。如果名称正好是它的名称。

在所有其他情况下,该计划格式不正确。

您必须考虑标准的前一段

  

2对于名称空间X和名称m,名称空间限定的查找集   S(X,m)定义如下:设S0(X,m)为全部的集合   X中的m的声明和X的内联命名空间集(7.3.1)。 如果   S0(X,m)不为空,S(X,m)为S0(X,m); 否则,S(X,m)为   所有命名空间的S(Ni,m)的并集由使用指令提名   在X及其内联命名空间集中。

编辑:对不起。我使用声明和using指令混合使用。在您的示例中,有一个使用声明。所以这个名字含糊不清。我代替

using B::i;

会有

using namespace B;

然后就不会有歧义。

你应该比较两个例子

第一个就是你展示的。

#include <iostream>

inline namespace A
{
    int i = 42;
};

namespace B 
{
    static const int i = 5;
};

using B::i;

int g= ::i;

int main() 
{
    std::cout << g << std::endl;

    return 0;
}

代码不会被编译,因为S(global,i)包含两个成员。

另一个例子

#include <iostream>

inline namespace A
{
    int i = 42;
};

namespace B 
{
    static const int i = 5;
};

using namespace B;

int g= ::i;

int main() 
{
    std::cout << g << std::endl;

    return 0;
}

代码将被编译,因为名称空间B中的名称i将不被考虑。