2017-05-26 46 views
0

我有一個模板類,確保基本上只能用2個枚舉中的1個實例化。現在我想根據它實例化的枚舉設置初始化器中模板參數的值。這樣的事情:初始化程序列表中的編譯時替換

enum class MyFirstEnum { red, green, orange }; 
enum class MySecondEnum { blue, yellow, red }; 

template <class T> 
class MyClass 
{ 
    static_assert(
     std::is_same<T, MyFirstEnum>::value || std::is_same<T, MySecondEnum>::value, 
     "Template parameter must be either MyFirstEnum or MySecondEnum" 
    ); 
public: 
    MyClass() 
     : value(std::is_same<T, MyFirstEnum>::value ? MyFirstEnum::red : MySecondEnum::blue) 
    { 
    } 
private: 
    T value; 

} 

但當然編譯器抱怨,因爲類型不匹配,三元不是編譯時的替代。有沒有辦法根據類型參數分配正確的值?

任何幫助表示讚賞。我僅限於C++ 11

+0

'value'不可能保持兩種類型的實例(即'MyFirstEnum','MySecondEnum') – nakiya

+0

'MyFirstEnum :: red'和'MySecondEnum :: blue'的值均爲0,所以也許只需使用'value(static_cast (0)'或者'value()並讓編譯器爲你初始化它 –

+0

@nakiya當然,爲什麼在初始化列表中存在三元組來填充正確的類型,所提供的代碼將不會編譯,因爲這是一個運行時檢查,但它需要編譯時檢查 –

回答

3

在你的榜樣,MyFirstEnum::redMySecondEnum::blue都有值爲0,那麼試試這個:

MyClass() 
    : value(static_cast<T>(0)) 
{ 
} 

或者只是:

MyClass() 
    : value(0) 
{ 
} 

或者,讓編譯器零初始化值你:

MyClass() 
    : value() 
{ 
} 

另一方面,如果不能保證初始v ALUE將始終爲0,那麼我建議定義每個enum一個traits結構,並讓它們指定所需的默認值:

enum class MyFirstEnum { red, green, orange }; 
enum class MySecondEnum { blue, yellow, red }; 

template<typename T> 
struct MyClass_traits 
{ 
}; 

template<> 
struct MyClass_traits<MyFirstEnum> 
{ 
    static const MyFirstEnum initial_value = MyFirstEnum::red; 
}; 

template<> 
struct MyClass_traits<MySecondEnum> 
{ 
    static const MySecondEnum initial_value = MySecondEnum::yellow; 
}; 

template <class T, typename traits = MyClass_traits<T> > 
class MyClass 
{ 
    static_assert(
     !(std::is_same<T, MyFirstEnum>::value || std::is_same<T, MySecondEnum>::value), 
     "Template parameter must be either MyFirstEnum or MySecondEnum" 
    ); 

public: 
    MyClass() 
     : value(traits::initial_value) 
    { 
    } 

private: 
    T value; 
}; 
0

根據雷米推薦的特質類。

enum class MyFirstEnum { red, green, orange }; 
enum class MySecondEnum { blue, yellow, red }; 

template<class T> 
struct Traits 
{ 
}; 

template<> 
struct Traits<MyFirstEnum> 
{ 
    static MyFirstEnum default_val() {return MyFirstEnum::red;} 
}; 

template<> 
struct Traits<MySecondEnum> 
{ 
    static MySecondEnum default_val() {return MySecondEnum::blue;} 
}; 

template <class T> 
class MyClass 
{ 
    static_assert(
     !(std::is_same<T, MyFirstEnum>::value || std::is_same<T, MySecondEnum>::value), 
     "Template parameter must be either MyFirstEnum or MySecondEnum" 
    ); 
public: 
    MyClass() 
     : value(Traits<T>::default_val()) 
    { 
    } 
private: 
    T value; 

} 

未經測試。