我偶然发现了here所描述的嵌套模板的同样问题。
以下代码:
# 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
}
只要返回类型中存在template
关键字,就可以使用MinGW 4.5(即gcc)进行编译,但这会使MSVC2010抱怨声明/定义不匹配:
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 !
删除template
关键字时,MSVC会在gcc生气时编译正常:
error: non-template 'Inner' used as template note: use 'Outer::template Inner' to indicate that it is a template
根据post linked above,MSVC似乎是错误的。所以我的问题:
如何调整上述代码以便使用MSVC和GCC进行编译? 我真的想避免这种可怕的预处理器黑客攻击:
# ifdef MSVC
# define nested_template
# else
# define nested_template template
# endif
然后使用nested_template
取悦MSVC,它不喜欢template
。
答案 0 :(得分:3)
实际上,define是在需要嵌套模板的许多地方进行交叉编译器支持的方法。 Boost也做到了!
另一种方法是将所有嵌套模板分隔在额外的标头中,并在MSVC和GCC中使用不同的包含模式。