我知道在编译时并不总是可以复制任意内存块,但既然我们得到了 constexpr 容器、虚拟方法和算法,为什么不使用 memcpy 呢?它也是一种算法。
此外,
std::bit_cast
看起来很像 std::memcpy
解决方法 reinterpret_cast
但它是 constexpr
. std::copy
使用迭代器标记为 constexpr
对于 C++20,因此类型可以以某种方式进行复制。 用法是复制或只是“重新解释”
constexpr
中的变量/数组。函数,std::bit_cast
没有解决前者AFAIK。特别是 question我的回答想用它。std::bit_cast
有什么特别的原因吗?可以是 constexpr 但 std::memcpy
不能? std::bit_cast
中的引用参数。和 std::copy
中的迭代器. C++20 bit_cast vs reinterpret_cast的相关回答从某处简要引用:
Furthermore, it is currently impossible to implement a constexpr bit-cast function, as memcpy itself isn’t constexpr. Marking the proposed function as constexpr doesn’t require or prevent memcpy from becoming constexpr, but requires compiler support. This leaves implementations free to use their own internal solution (e.g. LLVM has a bitcast opcode).
但它也没有详细说明不使其成为 constexpr。
请注意,我不问为什么
std::bit_cast
存在。我喜欢它,它提供了一个明确的意图而不是 std::memcpy
解决方法。
最佳答案
运行时代码中的 C++ 对象模型通常处理得有些松散。它有相当严格的规则,但是有一堆后门被允许或声明为 UB。后者意味着您仍然可以编写代码来执行此操作,但 C++ 不保证该代码的行为。
在持续评估(又名:代码的编译时执行)中,情况并非如此。对 constexpr
的限制专门用于让对象模型成为您必须遵循的真实事物,没有可行的后门。甚至它偶尔允许的那些也被明确要求格式错误并产生编译错误,而不是沉默的 UB。
基本上在运行时,您可以将内存视为存储字节。在编译时,你不能;你不被允许。即使在 constexpr
中使用动态分配在 C++20 中添加的代码,你不会玩很多你通常玩这类东西的游戏。memcpy
处理字节的存储,来回复制它们而不知道它们的含义。 bit_cast
知道源对象和目标对象,除非源对象和目标对象适合 bit_cast
,否则不允许这样做。 ing(即:可简单复制)。bit_cast
还有very specific restrictions如果您希望它在编译时工作,请查看这两个对象的内容。特别是,您不能 bit_cast
指针或包含任何类型指针的任何对象。或引用文献。
这是因为编译时的指针不仅仅是地址。为了捕捉 UB,编译时指针必须知道它指向的对象的真实动态类型。因此,在编译时不允许仅转换地址的指针转换。
关于c++ - 即使在 C++20 中 std::memcpy 也不是 constexpr 的原因是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64041869/