类模板中的Typedef评估

doc*_*doc 4 c++ templates typedef language-lawyer

下面的代码用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;
}
Run Code Online (Sandbox Code Playgroud)

clang错误信息:

main.cpp:9:30: error: no type named 'Container' in 'Traits<T>'
Run Code Online (Sandbox Code Playgroud)

编译器是否应该评估typedef而不用实际类型替换template参数?哪个编译器是对的?

clang:http://coliru.stacked-crooked.com/a/fef7725827074e4f

gcc:http://coliru.stacked-crooked.com/a/79e17031fcabcd83

Yak*_*ont 5

template <typename T>
struct Traits {
  typedef typename Traits<T>::Container Container;
};
Run Code Online (Sandbox Code Playgroud)

这是形成不良,无需诊断.没有T这样的上述(主要)专业化可能导致有效的代码.

另一种专业化的存在没有任何区别.编译器可以自由地执行任何操作,包括提供虚假错误消息.编译它是免费的.只有foo在程序中有其他名称的变量或者月亮是新的时,才可以自由地生成错误.如果这些是执行质量差的一些.

在实践中,这意味着编译器可以自由地假设主要特化对某些类型有效T(即,在其中没有无限递归),并且在相对不相关的代码中废弃,因为它做出了这个假设.