其中一个"哪个编译器是正确的"关于模板的问题。请考虑以下事项:
template<typename T>
class Container
{
public:
template<typename V>
class iterator;
};
template<typename T>
template<typename V>
class Container<T>::iterator
{
public:
iterator &operator++();
};
现在,当提供operator++
外联的定义时,它看起来像这样:
template<typename T>
template<typename V>
typename Container<T>::template iterator<V> &Container<T>::iterator<V>::operator++()
{
//do your thing
return *this;
}
对于4.8+和Clang 3.2+的任何GCC版本都可以编译它。但是,MSVC19 +没有,它特别不喜欢该定义中的template
关键字。它抱怨说它无法与声明和定义相匹配,因为它提供了它所寻找的内容和候选人&#34;他们都是一样的。如果template
被移除,因此仅使用typename Container<T>::iterator<V>
,MSVC就可以很好地编译它。然而,Clang和GCC将失败。
您可以在Compiler Explorer中试用它:live demo
那么谁是对的?由于GCC和Clang都有很长一段时间,所以我倾向于倾向于他们。但是,我想支持这三个。那么我要么将它移到课堂定义中还是使用#ifdef
?似乎错了,如果MSVC在这里出错,应该报告(除非这是一个已知问题)。
答案 0 :(得分:8)
您可以使用尾随返回类型来简化代码。无需typename
或template
:
template<typename T>
template<typename V>
auto Container<T>::iterator<V>::operator++() -> iterator<V> &
{
//do your thing
return *this;
}