是否可以从原始内存块反序列化没有默认构造函数的对象?

Vio*_*ffe 2 c++ language-lawyer c++17

我在写这个小工具,可以避免严格的别名冲突:

template <typename TargetType>
TargetType memory_cast(const void* const memoryPtr) noexcept
{
    static_assert(!std::is_reference_v<TargetType>);
    static_assert(std::is_trivially_copy_assignable_v<TargetType>);

    TargetType value;
    ::memcpy(&value, memoryPtr, sizeof(value));

    return value;
}
Run Code Online (Sandbox Code Playgroud)

我想到,如果TargetType它不是默认可构造的,它将失败,但是从技术上讲,这并不重要,因为我们已经具有对象的完整构造数据,只是没有对象实例本身可以将数据放入其中。无需调用UB即可在现代C ++中解决此问题的方法?

Nic*_*las 5

std::bit_cast使用C ++ 20之前实际上不可能在C ++标准的范围内完成您的建议。微小的可复制性(与is_trivially_copy_assignable_vBTW不同)允许在这种类型的活动实例的对象表示之间进行字节复制(可能使用它们之间的中间缓冲区)。但是您仍然需要一个活动实例来复制到其中。

确实,这是为什么将bit_cast其添加到C ++ 20 的很大一部分。

  • @NathanOliver:这不是“编译器魔法”;这是*法定*。标准说“bit_cast”将执行 X,因此它将执行 X。标准库不必由其他人实现。 (2认同)