在编译时而不是运行时创建由两个字节组成的值

问题描述 投票:0回答:2

我有一个可以用作uint8_t的枚举器,并且我想使用此枚举器的两个值的组合来创建一个类型为uint16_t的数字,其中leftmostrightmost] >字节由这两个枚举值确定。

然后我需要将此结果值用作存储多个unordered_map<uint16_t, something>值的something的关键元素类型。

因此,我想到了这段代码,该代码在运行时将两个枚举值解析为一个键。这些评论仅表明,实际问题所涉及的不仅仅是下面示例中显示的元素。

enum Value : uint8_t {
    V1, V2, V3, V4 // , ... , VN
};

static inline uint16_t compose(Value a, Value b) {
    return ((uint16_t) a << 8) | b;
}

static const unordered_map<uint16_t, something> elements = {
    { compose(Value::V3, Value::V1), something1 },
    { compose(Value::V4, Value::V4), something2 },
    { compose(Value::V1, Value::V2), something3 },
    // { ... }, { compose(Value::VA, Value::VB), somethingN }
};

如果我没记错的话,compose将在程序启动时被调用多次,并尝试在运行main之前初始化变量和常量。

现在是个大问题:

是否有更好的方法来在编译时而不是在运行时编写数字?

我可能会对数字进行硬编码而不是运行compose,但这将是一个非常丑陋且可能不安全的解决方案。

想象一下,如果我不得不切换两个或多个“ values”]的位置;这将需要对硬编码数字进行完整的修订,因此根本不是一个选择。

保持组成uint16_t的两个枚举值的名称也非常好,因此当我需要编辑与somethingV1相对应的V4时,我可以轻松找到它。] >

不幸的是,我不认为预处理器可以执行类似的操作,并且即使我使用了compose关键字,我也怀疑编译器是否能够优化inline

请帮助我。

我有一个可以用作uint8_t的枚举数,并且我想使用此枚举数的两个值的组合来创建一个uint16_t类型的数字,其中最左边和最右边的字节是......>

您可以将compose标记为constexpr功能。这样,编译器便可以将函数的结果用作编译时常量:

constexpr

在c ++ 20中,您可以将inline constexpr uint16_t compose(Value a, Value b) { ... } 设为compose函数。然后,它是保证

在编译时进行评估:
consteval

这里是consteval

c++ runtime unordered-map compile-time static-initialization
2个回答
1
投票

您可以将compose标记为constexpr功能。这样,编译器便可以将函数的结果用作编译时常量:

constexpr

0
投票

在c ++ 20中,您可以将inline constexpr uint16_t compose(Value a, Value b) { ... } 设为compose函数。然后,它是保证

在编译时进行评估:
consteval
© www.soinside.com 2019 - 2024. All rights reserved.