我正在努力理解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
我不明白该约束是如何检查我的示例的。我想了解确定的参考语境如何取决于该参考文献的使用?
答案 0 :(得分:0)
这一切都很简单,虽然是以令人困惑的方式写的。名称是名称空间的成员或其内联名称空间,或者名称是由某个其他名称空间的using指令引入的名称。如果这样的名称恰好是一个名称,那么它将被使用。
在您的代码示例中,S(global,i)有两个成员,一个是在内联命名空间A中定义的,另一个是使用声明引入的。所以存在歧义。
因此,考虑名称空间的顺序如下。 首先考虑名称空间本身及其内联名称空间。如果名称恰好是一个,则使用它。
Otherewise编译器考虑使用指令。如果名称正好是它的名称。
在所有其他情况下,该计划格式不正确。
您必须考虑标准的前一段
编辑:对不起。我使用声明和using指令混合使用。在您的示例中,有一个使用声明。所以这个名字含糊不清。我代替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 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将不被考虑。