C++11 为什么可以';我是否专门化std::tuple\u元素?

C++11 为什么可以';我是否专门化std::tuple\u元素?,c++11,clang,libstdc++,libc++,C++11,Clang,Libstdc++,Libc++,以下程序尝试为用户定义的类型foo的std::tuple\u元素提供专门化。不幸的是,clang-3.5拒绝使用libc++,但使用其他编译器或使用其他标准库的clang-3.5接受该程序。对吗?若否,原因为何 #include <utility> struct foo {}; namespace std { template<size_t, class> struct tuple_element; template<size_t i>

以下程序尝试为用户定义的类型
foo
std::tuple\u元素
提供专门化。不幸的是,
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;
}
#包括
结构foo{};
名称空间标准
{
模板结构元组元素;
模板
结构元组_元素{};
}
int main()
{
返回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)
$clang-3.5-std=c++11-stdlib=libc++-lc++test.cpp
test.cpp:11:8:错误:非模板结构“tuple\u元素”的显式专门化
结构元组_元素{};
^            ~~~~~~~~
生成1个错误。
$clang-3.5-std=c++11-lstdc++test.cpp
(没有错误)
$g++-4.9-std=c++11 test.cpp
(没有错误)

libc++
的实体实际上位于
std::\uu 1::
,这是
std
内部的内联命名空间。因此,您自己的转发声明
模板结构元组\u元素
实际上声明了一个不同的类模板,然后由于歧义而导致部分专门化失败(尽管错误消息具有误导性)


删除转发声明,它应该可以工作。

struct
替换为
class
也会修复一个警告。还要注意,转发声明会使程序格式错误,因为您可以在
std
中自由地专门化类型,但任何声明都是verboten(甚至是转发声明!)。构建中断是兼容的。@Yakk s/ill-format/UB/,太迂腐了。那么,你是说原始帖子中的代码格式不正确吗?换句话说,提供标准库组件的声明是不合法的?--您的代码将声明添加到
命名空间std
。因此,行为是未定义的。