2012-05-11 107 views
2

在下面的代碼中,Foo<T>::setValue適用於我的目的,除非其中T是類枚舉,名爲TYPE例如, Bar::TYPEBaz:TYPE專門針對枚舉類型參數的成員模板

因此,我很感謝Foo<T>::setValue的幫助,沒有命名BarBaz,因爲可能有幾十個這樣的類。

class Bar 
{ 
public: 
    enum TYPE{ ONE , TWO }; 
}; 

class Baz 
{ 
public: 
    enum TYPE{ SIX , TEN }; 
}; 

template<typename T> 
class Foo 
{ 
public: 
    void setValue(){} // Need a different setValue if T is a class enum 

private: 
    T m_value; 
}; 


int main() 
{ 
    Foo<int> f1; 
    Foo<Bar::TYPE> f2; 
    Foo<Baz::TYPE> f3; 
    return EXIT_SUCCESS; 
} 
+0

我不明白這個問題 - 如果類型是枚舉,你希望它做什麼?你可以在''is_enum''中使用'enable_if'(http://msdn.microsoft.com/en-us/library/bb982983.aspx) – Flexo

+0

@awoodland我來看看'is_enum'。如果'T'是一個類枚舉(稱爲TYPE),我想要一個不同的'Foo :: setValue'。 – Olumide

回答

5

你可以像這樣做:

#include <type_traits> 

template<typename T> 
class Foo 
{ 
public: 
    void setValue() { 
     setValueImpl<T>(); 
    } 
private: 
    template <class X> 
    typename std::enable_if<std::is_enum<X>::value, void>::type 
    setValueImpl() { std::cout << "Is enum" << std::endl; } 

    template <class X> 
    typename std::enable_if<!std::is_enum<X>::value, void>::type 
    setValueImpl() { std::cout << "Not enum" << std::endl; } 

    T m_value; 
}; 

凡使用基於is_enum型性狀enable_if挑選哪個版本。

該示例使用C++ 11 enable_ifis_enum,但boost也與pre-C++ 11類似。

+0

它的工作位不區分枚舉。我想我必須寫出一個能夠做到這一點的特質。 – Olumide

+1

@Olumide掛上,所以你想'Bar :: TYPE'和'Baz :: TYPE'是特殊情況,但其他一切都是默認的?如果這是你想要的,那麼有一個更簡單的解決方案。但是你必須在某處指定類型。你不能區分枚舉和不命名它們。 – Flexo

+0

我正在考慮將它們命名爲特質。 – Olumide

1

考慮一下:

#include <iostream> 

class Bar 
{ 
public: 
    enum TYPE{ ONE , TWO }; 
}; 

class Baz 
{ 
public: 
    enum TYPE{ SIX , TEN }; 
}; 

template<typename T> 
class Foo 
{ 
public: 
    template<typename C> void setValue(const C &m_value, ...) 
    { 
     std::cout << "normal" << std::endl; 
    } 

    template<typename C> void setValue(const C &m_value, typename C::TYPE fake = C::TYPE()) 
    { 
     std::cout << "TYPE'ed" << std::endl; 
    } 

private: 
    T m_value; 
}; 


int main() 
{ 
    Foo<int> f1; 
    Foo<Bar> f2; 
    Foo<Baz> f3; 

    f1.setValue(1); 
    f2.setValue(Bar()); 
    f3.setValue(Baz()); 

    return 0; 
} 
+1

閱讀更多關於SFINAE – inkooboo

+0

有趣的。沒有意識到我可以寫'Bar :: TYPE()' – Olumide