简体   繁体   English

如何在 int * 和 enum * 之间进行转换?

[英]How to convert between int * and enum *?

From some C legacy code I get a number of constants as int * .从一些 C 遗留代码中,我得到了一些作为int *的常量。 In the C++ part, I have an enum of underlying type int.在 C++ 部分,我有一个底层类型 int 的枚举。 Conversion between the enum and int on a single value basis works.基于单个值的枚举和 int 之间的转换有效。 However, conversion between int * and enum * is not possible.但是, int *enum *之间的转换是不可能的。 See code example below.请参阅下面的代码示例。

Why is that and how would I convert a pointer to some int values to a pointer to int enums and vice versa?为什么会这样,我如何将指向某些 int 值的指针转换为指向 int 枚举的指针,反之亦然? I kind of expect it to work since the single value conversions work and the underlying types are the same.我有点期望它能够工作,因为单值转换有效并且底层类型相同。 I read about What happens if you static_cast invalid value to enum class?我读到如果你 static_cast 无效值到枚举类会发生什么? but could not determine if potentially invalid values play a role here.但无法确定潜在的无效值是否在这里起作用。

int i = 3;
enum E : int;
E e;

e = static_cast<E>(i);   // ok
i = static_cast<int>(e); // ok

int *j;
E * f;

j = static_cast<int *>(&i); // ok
f = static_cast<E *>(&i);   // 'static_cast': cannot convert from 'int *' to 'E *'
j = static_cast<int *>(&e); // 'static_cast': cannot convert from 'E *' to 'int *'

// now use j and f
*j = *f;

Why is that?为什么?

From the compiler point of view int* and E* are pointers of different non-related types, that is why static_cast is not applicable here.从编译器的角度来看int*E*是不同的非相关类型的指针,这就是为什么static_cast在这里不适用。

How would I convert a pointer to some int values to a pointer to int enums and vice versa?我如何将指向某些 int 值的指针转换为指向 int 枚举的指针,反之亦然?

You might try reinterpret_cast instead of static_cast :您可以尝试reinterpret_cast而不是static_cast

f = reinterpret_cast<E *>(&i);
j = reinterpret_cast<int *>(&e);

From reinterpret_cast :reinterpret_cast

Any pointer to object of type T1 can be converted to pointer to object of another type cv T2任何指向类型 T1 的对象的指针都可以转换为指向另一个类型 cv T2 的对象的指针

However, note, that dereferencing f or j (ie with *f or *j ) will be a violation of the strict aliasing rule (for more details see the discussion below).但是,请注意,取消引用fj (即使用*f*j )将违反严格的别名规则(有关更多详细信息,请参阅下面的讨论)。 This means that this kind of conversion, though strictly possible, is usually not useful.这意味着这种转换虽然严格可行,但通常没有用。

The default 'base type' of an enum is int and can be explicitly specified in the OP.枚举的默认“基本类型”是int并且可以在 OP 中明确指定。 Logically the value stored at E* e where E is an enumeration with base type int is an int .从逻辑上讲,存储在E* e中的值,其中 E 是基本类型为int的枚举,是一个int It can't be statically cast.它不能静态转换。

There's no guarantee in C++ that an enum of base type (say) is layout compatible with short but even if the language tightened up that point there could be issues of type compatibility/在 C++ 中不能保证基本类型的enum (比如)与short布局兼容,但即使语言在这一点上收紧,也可能存在类型兼容性问题/

One issue is that E* to int*pi would violate type-safety because pi could be used to quietly set values outside the enumeration.一个问题是E*int*pi会违反类型安全,因为pi可用于在枚举之外安静地设置值。 Similarly int* to E* may violate type safety if the integer value isn't in the enumeration.类似地,如果整数值不在枚举中,则int*E*可能会违反类型安全。

Note however the standard makes a clear note that there's nothing to preclude an enum taking a value outside its defined set of values:但是请注意,标准明确指出,没有什么可以排除枚举在其定义的值集之外取值:

This set of values is used to define promotion and conversion semantics for the enumeration type.这组值用于定义枚举类型的提升和转换语义。 It does not preclude an expression of enumeration type from having a value that falls outside this range.它不排除枚举类型的表达式具有超出此范围的值。

See here: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3690.pdf (see note 95 bottom of p. 156)请参见此处: http : //www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3690.pdf (参见第 156 页的注释 95 底部)

The only case that could (if layout-compatibility were assured) be valid is E* to const int* because all values of E* are int s and the value cannot be (correctly) modified through the int * pointer without a further violation of the type system.唯一可能(如果布局兼容性得到保证)有效的情况是E*const int*因为E*所有值都是int并且不能(正确)通过int *指针修改该值而不进一步违反类型系统。

But I think the language definition is not that subtle.但我认为语言定义并没有那么微妙。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM