2017-05-26 20 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

[値]は、おそらく、すなわち(両方のタイプのインスタンスを保持することはできません'MyFirstEnum'、' MySecondEnum') – nakiya

+0

'MyFirstEnum :: red'と' MySecondEnum :: blue'は両方とも0の値を持っているので、 'value(static_cast (0)'または 'value()'コンパイラにゼロ初期化を依頼してください。 –

+0

@nakiyaもちろん、初期化されたリストに正しい型を記入するために3項があるのはなぜですか?これは実行時チェックであるため、提供されたコードはコンパイルされませんが、 –

答えて

3

MyFirstEnum::redMySecondEnum::blueの両方が0の値を持っているので、この試してみてください。

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

それとも:

MyClass() 
    : value(0) 
{ 
} 

あるいは、コンパイラは値をゼロ初期化してみましょうをあなた:

MyClass() 
    : value() 
{ 
} 

一方、最初のv ALUEはいつも、私は、各enumためtraits構造を定義する提案し、それらが必要なデフォルト値を指定しなければならず、0になります。

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; 

} 

テストされていません。あなたの例では

関連する問題