gpt4 book ai didi

c++11 - 如何编写通用的 "value-safe enum"?

转载 作者:行者123 更新时间:2023-12-02 23:22:10 25 4
gpt4 key购买 nike

C++11 提供了改进的枚举,其中 enum struct 。但这仍然会受到肯定的影响 - 直到你习惯它- 劣质旧enum最令人惊讶的陷阱:a的值enum struct E 类型的变量不必是任何枚举变量,但可以是 E 基础整数类型范围内的任何值:

enum struct X { one = 1};
X x = X(); // Fine! The value of x is int(0)
x = X(2); // Cool! The value of x is int(2)

在任何地方使用 enumenum struct 类型 E 的对象时,您必须捕获“不是 E 之一”的情况。

如何定义一个可以在以下环境中使用的通用类型代替enum struct(不一定是直接替代品)具有实例化类的对象不能的属性假设“枚举”值以外的值?

我的意思是不能在某种意义上如果对象会抛出而不是满足比假设任何不可区分的值(即捕获了这种情况它会变成“不是 E 之一”)。

我用恐吓引号说“枚举”,因为它似乎是不可避免的(不诉诸宏)这些值将被“枚举”由一系列整型模板参数组成,并且不能访问方式与 X::one 一样方便。

如果这是不可避免的,也没关系,只要“枚举”值成为可通过类型的枚举索引静态检索的常量。(这样客户端代码就可以很简单地将有意义的符号与索引或索引值,并封装这样一个方便的映射 - 例如在struct嵌套的匿名enum中!)

这个问题是否已经有一个我没有的广受好评的解决方案知道吗?

继续根据评论者请求(阿里)

Could you post some pseudo-code? It should show how you would like to use it.

以下是所需用法的一些指示(我认为):

/* 1 */
/* These 2 structs could just be tag-types X{}, Y{}
serving to distinguish value-safe-enums that
would otherwise be the same. But you could
also get more mileage out them, as shown...
*/
struct turn;
struct hand;

using vs_turn = val_safe_enum<turn,int,1,2>;
using vs_hand = val_safe_enum<hand,int,1,2>;

struct turn
{
// Want an anonymous scoped enum; only rvalue
enum {
right = vs_turn::which<0>(), // = 1
left = vs_turn::which<1>() // = 2
};
};

struct hand
{
enum {
right = vs_hand::which<0>(), //= 1
left = vs_hand::which<1>() // = 2
};
};
/* End 1 */

/* 2 */
char const * foo(vs_turn const & t) {
// Only 2 possibilities!
return int(t) == turn::right ? "right turn" : "left turn";
}
char const * foo(vs_hand const & h) {
return int(h) == hand::right ? "right hand" : "left hand";
}
/* End 2 */


vs_turn t1(0); // 3.a OK
vs_turn t2(turn::right); // 3b. OK
vs_hand h1(hand::left); // 3c. OK
vs_hand h2(1); // 3d. OK

t1 == vs_turn(turn::right); // 4. OK

t1 < t2; // 5. OK

t1 = t2; // 6. OK

int(t1) == turn::right; // 7. OK. Explicit conversion to underlying type.

/* 8 */
switch(int(t1)) {
case turn::right:
/* Something */ break;
case turn::left:
/* Something */;
// No default necessary!
}
/* End 8 */

vs_turn t3(3); // 9. Throw! Value out of range
vs_turn t4; // 10. Error. No default construction.

t1 == turn::right; // 11a. Error. No Conversion
t1 <= h1; // 11b. Error. No conversion.
t1 = turn::right; // 11c. Error. No conversion
t1 = h1; // 11d. Error. No conversion.
foo(turn::right); // 11e. Error. No conversion

最佳答案

struct C
{
enum E { a, b, c };

C(E e) : e(e) { if (e > c) throw logic_error; }

private:
E e;
};

更新:

template<typename T, T... E> struct Check;

template<typename T> struct Check<T> { void check(T) { throw logic_error; } }

template<typename T, T e0, T... E> struct Check<T, e0, E...>
{
void check(T e)
{
if (e != e0)
Check<T, E>::check(e);
}
}

template<typename T, T... E>
struct C
{
C(T e) : e(e) { Check<T, E...>::check(e); }

private:
T e;
}

关于c++11 - 如何编写通用的 "value-safe enum"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17131861/

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