C++ C++;类型‘;的强制转换无效;无效*’;键入‘;双人床’;

C++ C++;类型‘;的强制转换无效;无效*’;键入‘;双人床’;,c++,casting,void-pointers,C++,Casting,Void Pointers,如何将void指针强制转换为double,并保留存储在void指针中的确切二进制文件?我原以为这可以通过reinterpret\u cast(voidp)来实现,但g++不允许。我知道可以将void指针强制转换为整数,所以我尝试了重新解释强制转换(reinterpret\u cast(voidp)),但显然这也是无效的sizeof(double)和sizeof(void*)都是8,所以它不可能是大小的东西。我能做些什么来实现这一点吗 编辑:在这种情况下,双精度点不是由void指针指向的,而是/i

如何将void指针强制转换为double,并保留存储在void指针中的确切二进制文件?我原以为这可以通过
reinterpret\u cast(voidp)
来实现,但g++不允许。我知道可以将void指针强制转换为整数,所以我尝试了
重新解释强制转换(reinterpret\u cast(voidp))
,但显然这也是无效的
sizeof(double)
sizeof(void*)
都是8,所以它不可能是大小的东西。我能做些什么来实现这一点吗


编辑:在这种情况下,双精度点不是由void指针指向的,而是/is/void指针-指针本身包含我想要的数据,它不指向我想要的数据。

这完全不建议,但如果必须,请使用:

*reinterpret_cast<double*>(&voidp)
*重新解释铸件(&P)
void*某些数据=NULL;
double*as\u double=静态强制转换(一些无效数据);
double as_double\u copy=*as_double;
double as\u double\u copy\u one\u line=*静态\u cast(一些\u void\u数据);
显然,您希望在实际使用中对非空指针应用强制转换<代码>静态转换只能用于从一种指针类型转换为另一种指针类型。如果您想要指针的副本,您需要通过取消引用强制转换返回的指针来自己执行副本

是铸造方面的一个很好的资源。

类型双关的首选方法应该是
memcpy()

double d = 100;
void *x;
std::memcpy(&x, &d, sizeof x);

std::cout << x << '\n';

double d2;
std::memcpy(&d2, &x, sizeof d2);

std::cout << d2 << '\n';
用法示例:

void *p = ...;
double d = bit_cast<double>(p);
void*p=。。。;
双d=钻头铸造(p);

如果您进行类型双关,您应该了解所涉及类型的陷阱值以及编译器对陷阱和未指定值的行为。

直接内存重新解释,根据定义,意味着使用左值。最直接的方法是通过转换为引用类型来实现

double d = reinterpret_cast<double &>(voidp);

或者,在C语言中,您现在可以为此目的使用联合体。我不确定正式的权限是否已经进入C++,但它通常会在实践中工作。

将它转换成<代码>双*<代码>代码>双D**((双*)VoIP)< />代码>为什么要这样做?在什么情况下,您将在
void*
中存储
double
?“sizeof(double)和sizeof(void)都是8”*-您的意思是碰巧都是8吗?@clcto是的,这就是为什么您将指针传递给
double
,而不是
double
。您可能不想获取void*的地址,虽然也许这就是他想要做的。谁知道呢:)这就是我要找的-我想我应该澄清一下,void指针是double,它实际上没有指向任何东西。@Monchoman45:为什么要以
void*
的形式传递
double
?什么样的巫术迫使你走得那么低?@Monchoman45问题很清楚,但是大多数人认为你的代码做了一些正常的事情,你对代码的理解是错误的,而不是相信你。不过要做好准备,在执行严格别名优化的编译器中,这可能不会像预期的那样工作。他为什么要这样做?@LihO我不知道,但他明确要求采用
void*
的位模式,并获得具有相同位模式的
double
。@LihO实际上我可以想到一个用途:有许多回调API允许您将
void*
传递给回调。如果回调只接受一个double,并且用户希望避免将double放在堆上,而
void*
恰好足够大,那么直接将double作为
void*
值传递可能具有所需的性能特征。对于
assert()
memcpy()
来说,这是很好的。关于C++的正式许可:仍然明确禁止(UB)阅读不活跃的工会成员。我接受了这个答案,而不是我首先接受的答案(Avidanborisov的),因为你们都回答了我最初的问题,使用工会的建议被证明更有用。工会方法,除了一般导致UB外,还可能无法生成最佳代码:
memcpy()
,可能包含在
bit\u cast()
模板函数中,应该是正确、安全和方便的首选方法@蒙乔曼45
void *p = ...;
double d = bit_cast<double>(p);
double d = reinterpret_cast<double &>(voidp);
double d;
assert(sizeof d == sizeof voidp); // <- a static assert would be even better
memcpy(&d, &voidp, sizeof d);