以下代码使用g ++编译,但无法使用clang进行编译。
struct X;
template <typename T>
struct Traits
{
typedef typename Traits<T>::Container Container;
};
template <>
struct Traits<X>
{
typedef std::vector<X *> Container;
};
int main()
{
Traits<X>::Container container;
return EXIT_SUCCESS;
}
clang错误消息:
main.cpp:9:30: error: no type named 'Container' in 'Traits<T>'
编译器是否应该评估typedef而不用实际类型替换template参数?哪个编译器是对的?
答案 0 :(得分:5)
template <typename T>
struct Traits {
typedef typename Traits<T>::Container Container;
};
这是形成错误,无需诊断。没有T
使得上述(主要)专业化可能导致有效的代码。
另一种专业化的存在没有任何区别。编译器可以自由地执行任何操作,包括提供虚假错误消息。编译它是免费的。只有在程序中的其他地方有一个名为foo
的变量,或者月亮是新的时,才能自由生成错误。如果这些是执行质量差的话。
实际上,这意味着编译器可以自由地假设主要特化对某些类型T
有效(即,在其中没有无限递归),并且在相对不相关的代码中废弃,因为它使得假设