在初始化列表中编译时间替换

时间:2017-05-26 00:06:26

标签: c++ c++11 templates enums constexpr

我有一个模板类,确保基本上只用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

2 个答案:

答案 0 :(得分:3)

在您的示例中,MyFirstEnum::redMySecondEnum::blue的值均为0,因此请尝试以下操作:

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

或者只是:

MyClass() 
    : value(0)
{
}

或者,让编译器为您零值初始化值:

MyClass() 
    : value()
{
}

另一方面,如果无法保证初始值始终为0,那么我建议为每个traits定义enum结构,并让它们指定所需的默认值:

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;
};

答案 1 :(得分: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;

}

未经测试。