重新解释 C 中的强制转换 - 无法获取右值的地址

问题描述 投票:0回答:1

我有两个具有相同内存布局的结构体

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++ c rvalue-reference reinterpret-cast
1个回答
0
投票

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;

但是,任何有“需要”的程序都应该重新审查,目的是重新设计它以避免这种需要。

© www.soinside.com 2019 - 2024. All rights reserved.