One of those "which compiler is right" questions about templates. Consider following:
template<typename T>
class Container
{
public:
template<typename V>
class iterator;
};
template<typename T>
template<typename V>
class Container<T>::iterator
{
public:
iterator &operator++();
};
Now when providing a definition for the operator++
out-of-line it would look like this:
template<typename T>
template<typename V>
typename Container<T>::template iterator<V> &Container<T>::iterator<V>::operator++()
{
//do your thing
return *this;
}
And sure enough pretty much any version of GCC from 4.8+ and Clang 3.2+ can compile it. MSVC19+ however does not and it specifically dislikes the template
keyword in that definition. It complains that it cannot match the declaration and definition which is especially funny since it gives what it looked for and the "candidate" and they are both identical. If template
is removed so only typename Container<T>::iterator<V>
is used, MSVC compiles it just fine. Clang and GCC however will fail.
You can try it live at Compiler Explorer: live demo
So who is right? Since both GCC and Clang has this for a long time I tend to lean towards them. However I would like to support all three. So either I move it to in-class definition or use #ifdef
? Seems wrong and if MSVC is at wrong here it should be reported (unless it is a known issue).
You can simplify code by using trailing return type. No need for typename
or template
:
template<typename T>
template<typename V>
auto Container<T>::iterator<V>::operator++() -> iterator<V> &
{
//do your thing
return *this;
}
online compiler
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With