从一些C遗留代码中我获得了许多常量int *
。在C ++部分,我有一个基础类型int的枚举。单值基础上的枚举和int之间的转换有效。但是,int *
和enum *
之间的转换是不可能的。请参阅下面的代码示例。
为什么会这样,我如何将指向某些int值的指针转换为指向int枚举的指针,反之亦然?我期望它能够工作,因为单值转换工作和底层类型是相同的。我读到了What happens if you static_cast invalid value to enum class? ,但无法确定潜在的无效值是否在此处发挥作用。
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;
答案 0 :(得分:3)
为什么?
从编译器的角度来看,int*
和E*
是不同非相关类型的指针,这就是static_cast
不适用于此的原因。
如何将指向某些int值的指针转换为指向int枚举的指针,反之亦然?
您可以尝试使用reinterpret_cast
代替static_cast
:
f = reinterpret_cast<E *>(&i);
j = reinterpret_cast<int *>(&e);
任何指向T1类型对象的指针都可以转换为指向另一种类型cv T2
的对象的指针
但请注意,解除引用f
或j
(即*f
或*j
)将是严格别名的违规规则(有关详细信息,请参阅下面的讨论)。这意味着尽管严格可行,但这种转换通常没用。
答案 1 :(得分:0)
默认的基本类型&#39;枚举的内容是int
,可以在OP中明确指定。逻辑上存储在E* e
的值,其中E是基类型int
的枚举,是int
。它不能静态施放。
C ++中无法保证enum
基类型(比如说)与short
布局兼容,但即使语言收紧,也可能存在类型兼容性问题/
一个问题是E*
到int*pi
会违反类型安全性,因为pi
可用于在枚举之外静默设置值。
同样,如果枚举中的整数值不是int*
到E*
,则可能会违反类型安全。
但请注意,该标准明确指出,没有任何内容可以排除枚举值超出其定义的值集:
这组值用于定义枚举类型的提升和转换语义。它并不排除 枚举类型的表达式,其值超出此范围。
见这里:http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3690.pdf(参见第156页的注释95)
E*
到const int*
的唯通过E*
指针进行(正确)修改,而不会进一步违反类型系统。
但我认为语言定义并非那么微妙。