以下程序尝试为用户定义类型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)
答案 0 :(得分:7)
libc++
的实体实际位于std::__1::
,std
内的内联命名空间。所以你自己的前向声明template<size_t, class> struct tuple_element;
实际上声明了一个不同的类模板,然后部分特化由于模糊而爆炸(尽管错误信息是误导性的)。
删除前向声明,它应该有效。