c++ 类型特征表示“可轻易移动” - 示例

J.N*_*.N. 5 c++ type-traits move-semantics

我将“微不足道的可移动”定义为

调用移动构造函数(或移动赋值运算符)相当于将字节 memcpy 到新目标,而不是对移出的对象调用析构函数。

例如,如果您知道此属性成立,则可以使用它realloc来调整 std::vector 或内存池的大小。

失败的类型通常会有指向其内容的指针,需要由移动构造函数/赋值运算符更新。

我可以找到的标准中没有这样的类型特征。我想知道这是否已经有一个(更好的)名称,是否已经被讨论过以及是否有一些库利用了这样的特性。

编辑1:

从前几条评论来看,std::is_trivially_move_constructible并不std::is_trivially_move_assignable等同于我正在寻找的内容。我相信他们会给出true包含指向自身的指针的类型,因为读取您自己的成员似乎属于“琐碎”操作。

编辑2:

当正确实现时,指向自身的类型将不再是 trivially_move_constructible 或 move_assignable,因为 move ctor / move 赋值运算符不再是微不足道的。不过,我们应该可以说,只要我们不调用它的析构函数,unique_ptr 就可以安全地复制到新位置。

And*_*kin 5

我认为您需要的是std::is_trivially_relocatable提案P1144。不幸的是,该提案没有进入C++20,所以我们不应该指望它会在 2023 年之前出现。这很遗憾,因为这种类型特征将为std::vector和 类似类型带来巨大的优化。

\n

UPD。不,也不是 C++23。引用P1144 的作者:\xe2\x80\x9c 绝对不是 C++23,我敢打赌不是 C++26,很可能永远不会\xe2\x80\x9d。

\n


Mic*_*Roy 1

嗯,这让我想到......重载持有指向自身的指针的结构的类型特征非常重要。

以下代码演示了当 type_traits 未正确定义时,错误在代码中蔓延的速度有多快。

#include <memory>
#include <type_traits>

struct A
{
    int a;
    int b;
    int* p{&a};
};

int main()
{
   auto p = std::make_unique<A>();
   A a = std::move(*p.get());  // gets moved here, a.p is dangling.

   return  std::is_move_assignable<A>::value;  // <-- yet, this returns true.
}
Run Code Online (Sandbox Code Playgroud)

  • 我猜A是不正确的,它本身是不可移动的。它可能应该删除它的移动向量和移动分配。 (3认同)
  • 其实并不是。如果类型正确实现,它应该覆盖移动构造函数,并且它不再是微不足道的(尝试在上面添加适当的移动构造函数和“is_trivially_move_constructible”)。 (3认同)