未命名空间的行为在§7.3.1.1[namespace.unnamed]/P1中指定:
一种无名名称空间定义表现为如果它被替换为
inline_opt namespace unique { /* empty body */ }
using namespace unique ;
namespace unique { namespace-body }
其中inline
当且仅当它出现在 未命名名称空间定义中时,翻译单元中所有出现的unique
都被替换为相同的标识符,并且此 标识符与整个程序中的所有其他标识符不同。
特别要注意的是,不具名命名空间中的声明是在周边范围内通过使用指示符using namespace unique;
可见。
在代码片段A中,foo
是不合格的,所以编译器执行非限定名称查找(§3.4.1[basic.lookup.unqual])。这里相关的是条款的第2款规定:
2从提名的命名空间中的声明一使用指示符 成为封闭一个命名空间可见using指令;见 7.3.4。出于在3.4.1中描述的非限定名称查找规则的目的,来自 使用指令指定的名称空间的声明被认为是该封闭名称空间的成员。
因此,非限定名称查找找到foo
的两个声明,并且名称不明确。
在片段B中,A::foo
是合格的,因此适用合格的名称查找规则。由于A
是一个名称空间,所以适用的子条款是§3.4.3.2[namespace.qual]。作为与此有关,该规则在该条款的第2款规定:
对于一个命名空间X
和名称m
,命名空间限定查找设置 S(X,m)
定义如下:设S'(X,m)
是集合所有 的m
的声明X
和内联命名空间集X
(7.3.1)。如果S'(X,m)
不为空,则S(X,m)
为S'(X,m)
;否则, S(X,m)
是S(Ni,m)
获提名 所有命名空间Ni
通过using指令在X
其内嵌的命名空间集中的工会。
换句话说,合格的名称查找认为通过using指令提名的命名空间只有名字没有在指定的命名空间和其内嵌的命名空间集中找到。在这里,名称foo
位于名称空间A
中,因此未考虑使用指令提名的未命名名称空间,因此不存在歧义。
如果您在代码片段A中写入::foo
而不是foo
,那么将改为使用合格的查找规则,而且这将再次成为不含糊之处。
A是不合格的查询; B是合格的查找。不同的规则。 – 2014-09-27 03:40:17
我同意T.C,事实上,如果你简单地添加'void bar(){std :: cout << foo <<'\ n'; }'命名空间'A'内,但要警告*你添加它是相关的。 [** This Works **](http://ideone.com/azVxvU),例如,[** this not **](http://ideone.com/zt9NPA)。 – WhozCraig 2014-09-27 03:54:52