2011-05-01 24 views
1

這是my previous question的延續。專門編譯器錯誤C3855(MSVC9)中的嵌套類靜態函數結果

我想創建一個嵌套類模板的類模板,其中嵌套類模板有一個靜態函數,我想提供一個專業化。

這裏是我的測試代碼,它沒有提供嵌套類的專業化。請注意空類NullType的存在 - 這是我想要專門化嵌套類。

#include <cstdlib> 
#include <iostream> 
using namespace std; 

class NullType {}; 

template<class FooParam> struct Foo 
{ 
    template<class BarParam> struct Bar 
    { 
     static bool Magic(); 
    }; 
}; 

template<class FooParam> 
template<class BarParam> 
bool Foo<FooParam>::Bar<BarParam>::Magic() 
{ 
    return true; 
} 

int main() 
{ 
    bool b = Foo<int>::Bar<int>::Magic(); 
    cout << b << " "; 
    bool b2 = Foo<int>::Bar<NullType>::Magic(); 
    cout << b2 << " "; 

} 

此代碼編譯並按預期運行。輸出是:

1 1 

現在我想提供NullTypeBar::Magic一個專業化,有函數返回false。所需的輸出是:

1 0 

所以我試圖寫的專業化是這樣的:

template<class FooParam> 
template<> 
bool Foo<FooParam>::Bar<NullType>::Magic() 
{ 
    return false; 
} // COMPILER ERROR HERE C3855 

這個定義Foo::Bar::Magic()現有定義之前出現。

然而,該代碼產生一個編譯錯誤:

1>.\main.cpp(20) : error C3855: 'Foo<FooParam>::Bar<BarParam>': template parameter 'BarParam' is incompatible with the declaration 

...的閉括號上面所指出的。

我可以用什麼語法來提供這種專業化?我願意接受任何和所有的技術來實現我的主要目標(其他一切返回falseNullTypetrue),只要:

  1. 無需外部庫使用(增強)
  2. 它採用兼容標準的C++只有
  3. Foo是一個類模板,Bar是嵌套類模板或函數模板。返回falsetrue的函數必須是特殊化的或可重載的,以便調用NullType的代碼返回false,但其他所有操作都將返回true

我會在需要時澄清要求。

+0

根據14.7.3/18, 構件模板不能被其包圍類模板之前專門 是專門。 所以,你的要求可能無法得到滿足,因爲它是... – 2011-05-01 19:59:40

回答

1

一個快速解決方案是使用標準C++(5.2.8)的typeid運算符。所以,你的魔法()函數的內容如下:

template<class FooParam> 
template<class BarParam> 
bool Foo<FooParam>::Bar<BarParam>::Magic() 
{ 
    if (typeid(BarParam) == typeid(NullType)) 
     return false; 

    return true; 
} 

據我所知,編譯器都在實際執行的typeid和所屬類別的一些自由,但是==操作符是保證工作像你期望它來。需要注意的是,顯然有些編譯器爲了性能而默認不支持運行時類型信息;大多數應該有一個標誌來打開它。

2

沒有其封閉類的專業化的嵌套類/方法的專業化被兩個C++ 03和C++ 11禁止,如在@Ise紫藤的評論中提及。

但願採用超負荷工作,爲您以下解決方案?

#include <cstdlib> 
#include <iostream> 
using namespace std; 

class NullType {}; 

template<class FooParam> struct Foo 
{ 
    template<class BarParam> static bool Magic(BarParam); 
    static bool Magic(NullType); 
}; 

template<class FooParam> 
template<class BarParam> 
bool Foo<FooParam>::Magic(BarParam) 
{ 
    return true; 
} 

template<class FooParam> 
bool Foo<FooParam>::Magic(NullType) 
{ 
    return false; 
} 

int main() 
{ 
    bool b = Foo<int>::Magic(int()); 
    cout << b << " "; 
    bool b2 = Foo<int>::Magic(NullType()); 
    cout << b2 << " "; 
} 
2

另一可選變型是使用非嵌套性狀類:

class NullType {}; 

template<class FooParam> struct Foo 
{ 
    template<class BarParam> struct Bar 
    { 
     static bool Magic(); 
    }; 
}; 

template<class T> struct bool_trait 
{ 
    static const bool value = true; 
}; 

template<> struct bool_trait<NullType> 
{ 
    static const bool value = false; 
}; 

template<class FooParam> 
template<class BarParam> 
bool Foo<FooParam>::Bar<BarParam>::Magic() 
{ 
    return bool_trait<BarParam>::value; 
}