我有以下代码:
void (* point)();
point=prova;
unsigned long int imm8 = point<<24;
...
void prova(){
...
}
第三行代码我有错误:
二进制的无效操作数&lt;&lt; (有'void(*)()'和'int')
我正在尝试将移位运算符应用于函数指针,但是我收到以下错误。我怎么办?
答案 0 :(得分:3)
我不明白为什么要这样做,但错误是正确的,5.8
移位运算符部分中的草案C ++标准说明了;
操作数应为整数或无范围的枚举类型,并执行整体促销。[...]
如果需要,您可以使用reinterpret_cast将其转换为整数类型(uintptr_t)。链接引用包含以下示例:
int i = 7;
// pointer to integer and back
uintptr_t v1 = reinterpret_cast<uintptr_t>(&i); // static_cast is an error
警告
这种类型的转换只是有条件支持的,我们可以从C ++草案标准部分5.2.10
重新解释演员看到这一点,其中说:
将函数指针转换为对象指针类型,反之亦然 有条件支持。这种转换的意义是 实现定义,但实现支持 双向转换,将一种类型的prvalue转换为 另一种类型和背面,可能具有不同的cv-资格, 将产生原始指针值。
答案 1 :(得分:2)
没有便携的方法可以做到这一点。
该标准保证您可以将void*
转换为uintptr_t
而不会丢失信息 - 但它并不能保证uintptr_t
存在。符合标准的实现可能没有足够宽的整数类型来保存转换的指针而不会丢失信息。
即使uintptr_t
存在,该语言也只保证您可以将void*
转换为uintptr_t
而不会丢失信息。符合权限可能具有,例如,64位对象指针,64位uintprt_t
和128位函数指针。
在大多数实现中,您可能可以将函数指针转换为uintptr_t
而不会丢失信息。 (我认为POSIX保证了这一点,尽管ISO C和C ++标准没有。)
完成后,可能使用reinterpret_cast
,你有一个无符号整数,你可以随意移动。
这种转变的结果几乎肯定是毫无意义的垃圾。 C ++并不能阻止你在脚下射击,这就是你想要做的事情。
答案 2 :(得分:0)
这样做应该没有有效的原因。但是,您可以通过首先转换为unsigned long int
unsigned long int imm8 = reinterpret_cast<unsigned long int >(point)<<24;
此处reinterpret_cast
完成将指针视为unsigned long int
。请注意,它不可移植,可能会丢失数据。