2011-11-21 59 views
2

我偶然發現了嵌套模板here的相同問題。針對MSVC2010的嵌套模板解決方法?

以下代碼:

# 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 
} 

編譯正常使用MinGW 4.5(即GCC)只要template關鍵字存在於返回類型,但是這使得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

  • 如果不可能,如何重構/重新設計代碼以避免嵌套模板大小寫?

回答

3

實際上,定義是在需要嵌套模板的很多地方爲交叉編譯器提供支持的方法。 Boost也是這樣做的!

另一種方法是將所有嵌套的模板分離到額外的頭文件中,並在MSVC和GCC中包含不同的包含路徑。

+0

我不知道。 boost庫/庫是在哪裏完成的?我想看看助推器開發人員如何處理它。 – overcoder

+0

@overcoder:IIRC它用於'boost :: function'庫中。我認爲這不是直接針對MSVC,而是其他編譯器也遇到了這個問題。實際上,這個定義應該在Boost的配置頭文件中(或者在那裏的某個地方)。 – Xeo

+0

很高興聽到您的快速回復!我會檢查一下。 – overcoder