为什么我不能专门化std :: tuple_element?

时间:2015-07-23 20:42:40

标签: c++11 clang libstdc++ libc++

以下程序尝试为用户定义类型std::tuple_element提供foo的特化。不幸的是,clang-3.5使用libc ++拒绝它,但使用其他编译器或使用clang-3.5的其他标准库接受该程序。这是对的吗?如果不是,为什么不呢?

#include <utility>

struct foo {};

namespace std
{
    template<size_t, class> struct tuple_element;
    template<size_t i>
    struct tuple_element<i, foo> {};
}

int main()
{
    return 0;
}

编译器输出:

$ clang-3.5 -std=c++11 -stdlib=libc++ -lc++ test.cpp
test.cpp:11:8: error: explicit specialization of non-template struct 'tuple_element'
struct tuple_element<i, foo> {};
       ^            ~~~~~~~~
1 error generated.

$ clang-3.5 -std=c++11 -lstdc++ test.cpp
(no error)

$ g++-4.9 -std=c++11 test.cpp
(no error)

1 个答案:

答案 0 :(得分:7)

libc++的实体实际位于std::__1::std内的内联命名空间。所以你自己的前向声明template<size_t, class> struct tuple_element;实际上声明了一个不同的类模板,然后部分特化由于模糊而爆炸(尽管错误信息是误导性的)。

删除前向声明,它应该有效。