为什么我不能专精 std::tuple_element?
Why can't I specialize std::tuple_element?
以下程序试图为用户定义类型 foo
提供 std::tuple_element
的特化。不幸的是,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)
libc++
的实体实际上在 std::__1::
,std
内的一个内联命名空间。所以你自己的前向声明 template<size_t, class> struct tuple_element;
实际上声明了一个不同的 class 模板,然后部分专业化由于歧义而爆炸(尽管错误消息具有误导性)。
删除前向声明,它应该可以工作。
以下程序试图为用户定义类型 foo
提供 std::tuple_element
的特化。不幸的是,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)
libc++
的实体实际上在 std::__1::
,std
内的一个内联命名空间。所以你自己的前向声明 template<size_t, class> struct tuple_element;
实际上声明了一个不同的 class 模板,然后部分专业化由于歧义而爆炸(尽管错误消息具有误导性)。
删除前向声明,它应该可以工作。