gpt4 book ai didi

c++ - constexpr 的使用是否对非常量成员有效

转载 作者:行者123 更新时间:2023-11-30 02:54:05 25 4
gpt4 key购买 nike

背景

我要实现的目标:我正在尝试实现类似于 Java 枚举的东西(即具有一些附加功能的枚举)。我想出了一个使用两个类的解决方案,其中一个类表示一个值,另一个类作为可能值的枚举,使用静态变量来表示每个值。我希望它成为枚举的真正替代品,包括在模板实例化中使用枚举值的可能性。为此,枚举值需要是常量表达式 (constexpr)。但是,我不确定我是否正确使用了 constexpr。

代码

这是我想出的代码:

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 类保存了每个值的信息并提供了一些额外的功能(这里它存储了可以使用 getFoo() 函数访问的额外值 m_foo) .枚举本身由包含静态 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 和 clang 下正确编译且没有任何警告,但我不确定我是否正确使用了 constexpr。问题是虽然 EnumType 构造函数和转换运算符 operator Enum() 是 constexpr,但它们都访问变量 m_IDm_foo 不是常量(因为我需要赋值运算符)。

最佳答案

这很好,文字类型的成员是允许修改的。

为了在常量表达式中使用该类型,您必须使用常量参数构造它,但这没关系,因为您这样做了;

static constexpr EnumType A = EnumType(EnumType::val_A, 5);

构造的对象是一个有效的常量表达式,因此可用于初始化constexpr 变量A。您不修改对象的成员,因此它们是否可修改并不重要。

Clang 对常量表达式特别严格,如果你做错了什么就会报错。

这个对象可以用在需要常量表达式的地方:

constexpr EnumType A5(EnumType::val_A, 5);

例如

constexpr int i = A5.getFoo();

这个对象不能:

EnumType A6(EnumType::val_A, 6);
constexpr int i = A6.getFoo(); // error

关于c++ - constexpr 的使用是否对非常量成员有效,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17361103/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com