MSVC2010的嵌套模板解决方法?

时间:2011-11-21 06:46:04

标签: c++ templates

我偶然发现了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

  • 如果不可能,如何重构/重新设计代码以避免嵌套模板的情况?

1 个答案:

答案 0 :(得分:3)

实际上,define是在需要嵌套模板的许多地方进行交叉编译器支持的方法。 Boost也做到了!

另一种方法是将所有嵌套模板分隔在额外的标头中,并在MSVC和GCC中使用不同的包含模式。