I stumbled on the same problem of nested templates described here.
The following code :
# include <cstdlib> // for std::size_t
template<std::size_t N>
class Outer
{
public :
template<typename T>
class Inner
{
public :
inline Inner<T> & operator ++ (void) ;
inline Inner<T> operator ++ (int) ;
} ;
} ;
template<std::size_t N>
template<typename T>
inline typename Outer<N>::template Inner<T> & Outer<N>::Inner<T>::operator ++ (void)
{ // ^^^^^^^^ Point Of Interest : MSVC is the only one who complains
// preincrement
}
template<std::size_t N>
template<typename T>
inline typename Outer<N>::template Inner<T> Outer<N>::Inner<T>::operator ++ (int)
{ // ^^^^^^^^ Point Of Interest
// postincrement
}
compiles fine with MinGW 4.5 (i.e. gcc) as long as the template keyword is present in the return type, but this makes MSVC2010 complain about declaration/definition mismatch :
error C2244: 'Outer::Inner::operator ++' : unable to match function definition to an existing declaration 1> definition 1> 'Outer::Inner &Outer::Inner::operator ++(void)' 1> existing declarations 1> 'Outer::Inner Outer::Inner::operator ++(int)' 1> 'Outer::Inner &Outer::Inner::operator ++(void)' <- This is what it wants !
When removing the template keyword, MSVC compiles fine while gcc becomes angry :
error: non-template 'Inner' used as template note: use 'Outer::template Inner' to indicate that it is a template
Accoding to the post linked above, MSVC seems to be the faulty. So my questions :
-
How to adapt the above code in order to compile with both MSVC and GCC ?
I really want to avoid this awful preprocessor hack :# ifdef MSVC # define nested_template # else # define nested_template template # endif
And then use nested_template to please MSVC where it doesn’t like template.
- If impossible, how to refactor/redesign the code to avoid the nested templates case ?
Actually, the define is the way to go for cross compiler support in so many places where you need the nested template. Boost does it too!
The alternative is to seperate all your nested templates in extra headers and have different include pathes in MSVC and GCC.