内联命名空间中对命名空间的模糊引用

时间:2014-08-21 21:04:34

标签: c++ g++ c++14 clang++ inline-namespaces

假设以下代码:

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 { }
         { 
         ^

哪个编译器在这里做正确的事情?

2 个答案:

答案 0 :(得分:13)

GCC是正确的:

  

内联命名空间的成员可以在大多数方面使用,就像它们是封闭命名空间的成员一样。具体而言,内联命名空间及其封闭命名空间都被添加到依赖于参数的查找(3.4.2)中使用的关联命名空间集合中,只要其中一个是,并且 a 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

答案 1 :(得分:5)

GCC是正确的。

N3797表示,

  

和使用指令(   7.3.4)对于未命名的命名空间,内联命名空间的名称隐式插入到封闭的命名空间中(   7.3.1.1)。

因此,test::detailtest::v1::detail的名称空间不同,因此test::detail的查找不明确。标准非常明确,test::detail的查找应该包含test::v1::detail,本节中有很多引号可以支持这一点,但没有说明它们应该被视为相同的命名空间。

可以说,我会说Clang的行为更优越,但GCC是正确的。