2013-04-02 103 views
2

我有枚舉類型,爲此我重載了operator>>重載操作符>>對於所有枚舉類型

std::istream& operator >>(std::istream &is,MyEnum& enumVar) 
{ 
    int intVal; 
    is>>intVal; 
    enumVar = intVal; 
    return is; 
} 

如何避免編寫這些代碼爲今後所有enum類型,即如何編寫功能,因此它適用於所有enum類型?

+0

你可以使用'templates'來實現你的方法的通用性,但您將需要使用的約束機制,以確保只有您枚舉被接受參數。不幸的是,C++不支持「約束」。 –

+0

我知道我可以做一些模板和boost :: enable_if,但我真的不明白它是如何工作的 – user152508

+0

上的任何鏈接? –

回答

4

使操作模板,使其僅在模板參數(使用enable_if)枚舉:

#include <type_traits> 

template<typename T> 
typename std::enable_if<std::is_enum<T>::value, std::istream&>::type 
operator >>(std::istream &is, T& enumVar) 
{ 
    std::cout << "enum\n"; // just to see it is this one that gets used 
    int intVal; 
    is >> intVal; 
    enumVar = static_cast<T>(intVal); // note the explicit cast to make it legal 
    return is; 
} 

如果你沒有C++ 11 avaliable,您可以使用升壓轉換器的type_traits庫。

看到你的評論,你不知道究竟是如何enable_if作品,這裏是一個link with a detailed explanation.

總之,enable_if模板成對出現 - 一個與第二個模板參數的成員的typedef type當條件(第一個模板參數)爲true,並且當條件爲假時沒有該typedef。具有假條件的模板實例化無效,因爲成員typedef不存在。然後這樣的實例化(而不是一個硬編譯器錯誤)從過載設置中丟棄以用於以後的重載解析。另請閱讀關於SFINAE

編輯:助力的enable_if工作略有不同於標準的。二者必選其一:

boost::enable_if < boost::is_enum<T>, std::istream& >::type 
       // ^^^^^^^^^^^^^^^^^ 
       // expects a type 

boost::enable_if_c < boost::is_enum<T>::value, std::istream& >::type 
        // ^^^^^^^^^^^^^^^^^^^^^^^^ 
        // expects a value 
+0

謝謝。我使用boost,所以我用你的代碼中的boost ::替換了std ::。而不幸的是我收到編譯器錯誤:錯誤C2923:'boost :: enable_if':'boost :: is_enum ::值'不是參數'Cond'的有效模板類型參數 – user152508

+0

你可以顯示代碼不編譯? – jrok

+0

模板 類型名稱的boost :: enable_if <提高:: is_enum ::值,標準:: istream的&> ::型 操作者>>(標準:: istream的&是,T&enumVar) { 的std :: COUT << 「枚舉\ n」 個; int intVal; is >> intVal; enumVar = static_cast (intVal); //注意顯式投射使其合法 返回是; } – user152508