我有两个具有相同内存布局的结构体
struct Temp
和struct MyTemp
,我想将struct Temp
类型的返回值转换为struct MyTemp
类型,例如,在C++中,我可以通过单个方法实现这个目标像这样的行(没有任何临时变量):
#include <utility>
struct Temp {
int a;
int b;
};
struct MyTemp {
int a;
int b;
};
struct Temp get_temp(int a, int b) {
struct Temp temp = {
.a = a,
.b = b,
};
return temp;
}
int main() {
struct MyTemp mt = reinterpret_cast<MyTemp &&>(std::move(get_temp(1, 2)));
}
但是,我在 C 中找不到等效项,例如,C 中的以下代码无法编译:
struct Temp {
int a;
int b;
};
struct MyTemp {
int a;
int b;
};
struct Temp get_temp(int a, int b) {
struct Temp temp = {
.a = a,
.b = b,
};
return temp;
}
int main() {
struct MyTemp mt = *(struct MyTemp *)&get_temp(1, 2);
// error: cannot take the address of an rvalue of type 'struct Temp'
}
所以我的问题是,有没有办法做我在 C++ 中做的同样的事情?如果没有,为什么?而为什么
std::move
可以绕过这个麻烦呢?
C 中将内存重新解释为不同类型的标准方法是复制字节或使用联合。这些都不会仅对值(不是左值的值)进行操作。您将需要使用临时对象,如下所示:
struct MyTemp m;
memcpy(&m, & (struct Temp) { get_temp(1, 2) }, sizeof m);
或:
struct MyTemp m = (union { struct Temp t; struct MyTemp m; }) { get_temp(1, 2) } .m;
但是,任何有“需要”的程序都应该重新审查,目的是重新设计它以避免这种需要。