【问题标题】:What is the proper way of casting objects to unrelated objects in C++在 C++ 中将对象转换为不相关对象的正确方法是什么
【发布时间】:2021-07-30 19:27:14
【问题描述】:
#include <iostream>

class c1{
};

class c2{
};

int main(){
 c1 a;
 c2 b;
 //b = static_cast<c2>(a);   <-- will not compile
 
b = *reinterpret_cast<c2*>(&a);
  
 return 0;
}

b = static_cast&lt;c2&gt;(a); 将不会编译并出现此错误:

no matching conversion for static_cast from 'c1' to 'c2'

使用reinterpret_cast 并执行bit cast 是实现此目的的唯一方法吗?

【问题讨论】:

  • 没有尝试过bit_cast,因为它是 C++20,但它们应该是唯一的方法。可能相关:C++20 bit_cast vs reinterpret_cast
  • 你为什么不使用union
  • @Ranoiaetep 我的意思是我正在使用上面的reinterpret_cast 进行手动位转换,这也是一种位转换。
  • 您可能需要考虑 - "...每当尝试通过 AliasedType 类型的 glvalue 读取或修改 DynamicType 类型的对象的存储值时,行为是未定义的除非满足以下条件之一:..." en.cppreference.com/w/cpp/language/reinterpret_cast
  • 您的代码有未定义的行为。一个合适的方法是编写用户定义的转换运算符或赋值运算符。

标签: c++


【解决方案1】:

正确的方法是提供一种将一种转换为另一种的方法。有不同的方法可以做到这一点,这是一种方法:

struct c2;
struct c1{
    explicit operator c2 ();
};

struct c2{ };

c1::operator c2() { return {};}

int main(){
 c1 a;
 c2 b;
 b = static_cast<c2>(a);
  
 return 0;
}

但是,如果你坚持“无关”……

在 C++ 中将对象转换为不相关对象的正确方法是什么

没有。

reinterpret_cast 是使编译器静默的好方法,但b = *reinterpret_cast&lt;c2*&gt;(&amp;a); 是未定义的行为。通常reinterpret_cast 被认为是一个神奇的任意演员阵容,但事实并非如此。请参阅here 以了解已定义的相当有限的案例列表。不相关类型的对象之间的转换不在列表中。

【讨论】:

  • 我将不得不阅读有关std::bit_cast 的信息,尽管如果“不相关”包括sizeof(c1)sizeof(c2) 之间没有关系,那么对于 C++20,这个答案也不需要更新 afaik。无论如何,“正确”的方式是进行“正确”的转换;)
  • 如果它们的大小相同,为什么这是未定义的?它的字面意思是interpret this chunk of memory as this type,看起来很明确。就像 C 中的普通比特猫一样。
  • 我也在 g++ 上使用过-fsanitize=undefined,它在运行时不会产生错误,我不认为这是 UB 的一个难题,因为对象大小是相同的。
  • 最后,链接中的第 11 点显示A pointer to member object of some class T1 can be converted to a pointer to another member object of another class T2。这似乎是我在这里做的?
  • @Dan 是的,您只是将c1* 类型的指针 转换为c2* 类型的指针。这么多是明确定义的。没有定义的是访问一个c1对象as-if它是一个不相关的c2对象,当你取消引用转换的指针并分配结果到b。见what is type punning & what is the purpose of it?what happens if i use it or not use it?What is the strict aliasing rule
猜你喜欢
  • 2017-01-27
  • 2010-12-20
  • 1970-01-01
  • 1970-01-01
  • 2011-12-13
  • 1970-01-01
  • 1970-01-01
  • 2013-09-04
  • 2010-10-03
相关资源
最近更新 更多