内联命名空间中对命名空间的不明确引用
Posted
技术标签:
【中文标题】内联命名空间中对命名空间的不明确引用【英文标题】:Ambiguous reference to namespace within an inline namespace 【发布时间】:2014-10-15 15:38:03 【问题描述】:假设以下代码:
namespace test
namespace detail
inline namespace v1
namespace detail
void foo()
int main()
test::detail::foo();
As we can see,这段代码用Clang编译;不是 with GCC,但是 - GCC 抱怨对 namespace detail
的引用不明确:
main.cpp:20:11: error: reference to 'detail' is ambiguous
test::detail::foo();
^
main.cpp:4:5: note: candidates are: namespace test::detail
^
main.cpp:10:9: note: namespace test::v1::detail
^
哪个编译器在这里做正确的事情?
【问题讨论】:
Clang apparently gets others things about inline namespaces wrong,设计或遗漏。 【参考方案1】:GCC 是正确的。
N3797 指出,
和一个 using- 指令 ( 7.3.4 命名内联命名空间的)被隐式插入到封闭的命名空间中,就像未命名的命名空间( 7.3.1.1)。
因此,test::detail
与test::v1::detail
不是同一个命名空间,因此test::detail
的查找是不明确的。标准非常清楚test::detail
的查找应该包括test::v1::detail
,本节中有很多引号支持这一点,但没有说明它们应该被视为同一个命名空间。
可以说,我会说 Clang 的行为更优越,但 GCC 的行为是正确的。
【讨论】:
【参考方案2】:GCC 是正确的:
内联命名空间的成员可以在大多数情况下使用,就好像它们是封闭命名空间的成员一样。具体来说,内联命名空间及其封闭命名空间都被添加到参数相关查找(3.4.2)中使用的关联命名空间集合中,只要其中一个是,一个using-directive对于未命名的命名空间(7.3.1.1),命名命名空间的名称被隐式插入到封闭的命名空间中。此外,内联命名空间的每个成员随后都可以显式实例化(14.7.2)或显式特化(14.7.3),就好像它是封闭命名空间的成员一样。最后,通过显式限定在封闭的命名空间中查找名称 (3.4.3.2) 将包括由 using-directive 引入的内联命名空间的成员,甚至如果在封闭的命名空间中有该名称的声明。
(这是旧 n3337 编号中的 7.3.1/8)
我相信你看到的是Clang bug #10361。
【讨论】:
以上是关于内联命名空间中对命名空间的不明确引用的主要内容,如果未能解决你的问题,请参考以下文章
[C/C++]C++的命名空间,缺省参数,引用,auto关键字,内联函数等
C++入门语法第一篇:(命名空间缺省参数函数重载引用内联函数)