背景有效使用constexpr的
我想要實現:我想實現像一個Java枚舉(即枚舉,有一些額外的功能。) 。我想出了一個使用兩個類的解決方案,其中一個類表示一個值,另一個表示使用靜態變量來表示每個值的可能值的枚舉。我希望它是一個真正的枚舉替代,包括在模板實例化中使用枚舉值的可能性。爲此,枚舉值需要是一個常量表達式(constexpr)。但是,我不確定是否正確使用了constexpr。是與非const成員
守則
這裏是我想出了代碼:
class EnumType {
public:
enum Enum {val_A, val_B, val_C};
friend class EnumTypeList;
EnumType()
: m_ID(val_A), m_foo(0) {}
constexpr operator Enum() const {return m_ID;};
constexpr unsigned int getFoo() const {return m_foo;};
protected:
constexpr EnumType(const Enum v, const int foo)
: m_ID(v), m_foo(foo) {}
private:
Enum m_ID;
int m_foo;
};
class EnumTypeList {
public:
static constexpr EnumType A = EnumType(EnumType::val_A, 5);
static constexpr EnumType B = EnumType(EnumType::val_B, 4);
static constexpr EnumType C = EnumType(EnumType::val_C, 8);
};
類EnumType
保存每個值的信息,並提供一些額外的功能(這是存儲附加價值m_foo可以使用getFoo()
功能訪問)。枚舉本身由包含靜態constexpr變量的EnumTypeList
表示,其中每個變量表示枚舉的可能值。此代碼可以讓我在下面的代碼使用這些變量從EnumTypeList
代替EnumType::Enum.
即使在模板中,如:
template <EnumType::Enum T>
class Test {
public:
void test() {
std::cout << "Enum is not A" << std::endl;
}
};
template <>
class Test<EnumType::val_A> {
public:
void test() {
std::cout << "Enum is A" << std::endl;
}
};
int main() {
Test<EnumTypeList::A> a;
a.test();
Test<EnumTypeList::B> b;
b.test();
// this shouldn't compile
/*EnumType x = EnumTypeList::C;
Test<x> c;
c.test();*/
}
這個工程,我所期望的 - 我可以代替模板中使用的值從EnumTypeList
的EnumType::Enum
實例如上所示,但我不能EnumType x = EnumTypeList::C;
的問題
當代碼編譯正確,而不在gcc和鐺任何警告做到這一點,我不知道我是否正確地使用constexpr。問題是,儘管EnumType
構造函數和轉換運算符operator Enum()
是constexpr,但它們都訪問變量m_ID
和m_foo
,這些變量不是常量(因爲我需要賦值運算符)。