【问题标题】:c++ type trait to say "trivially movable" - examples ofc ++类型特征说“平凡可移动” - 的例子
【发布时间】:2017-08-18 03:14:10
【问题描述】:

我会通过

来定义“平凡的可移动”

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

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

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

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

编辑 1:

从最初的几个 cmets 开始,std::is_trivially_move_constructible 和 std::is_trivially_move_assignable 并不等同于我正在寻找的内容。 我相信他们会给包含指向自己的指针的类型提供true,因为读取您自己的成员似乎属于“微不足道”的操作。

编辑 2:

如果实现得当,指向自身的类型将不再是 trivially_move_constructible 或 move_assignable,因为移动 ctor / 移动赋值运算符不再是微不足道的。 不过,如果我们不调用其析构函数,我们应该可以说可以安全地将 unique_ptr 复制到新位置。

【问题讨论】:

  • std::is_trivially_move_constructible 和 std::is_trivially_move_assignable 似乎是你所追求的
  • std::is_trivially_copyable() 不是已经涵盖了您想要的内容吗?
  • 问题是这个概念与标准中类似名称的函数所表达的概念不太一样,尤其是关于跳过析构函数的部分。
  • 根据 cplusplus.com “一个平凡的移动构造类是一个类(用类,结构或联合定义):使用隐式定义的移动构造函数。没有虚拟成员。它的基类和非-static 数据成员(如果有的话)本身也是微不足道的可移动构造类型。”这意味着 unique_ptr 将不匹配。
  • 普通可复制似乎很合适。 memcpy 的前提是该类型是可简单复制的,而您的自引用对象示例则不是。

标签: c++ move-semantics typetraits


【解决方案1】:

我认为您需要的是来自提案P1144 的std::is_trivially_relocatable。不幸的是,该提案没有进入C++20,所以我们不应该在 2023 年之前期待它。这很可悲,因为这种类型特征将为 std::vector 和类似类型提供很好的优化。

【讨论】:

    【解决方案2】:

    嗯,这让我开始思考……重载包含指向自身的指针的结构的类型特征非常重要。

    以下代码演示了当 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.
    }
    

    【讨论】:

    • 我猜 A 是不正确的,它本身是不可移动的。它可能应该删除它的移动 ctor 和移动分配。
    • 是的。这意味着“读取你自己的成员”不会也不应该属于“琐碎”的操作......
    • 其实不是。如果类型被正确实现,它应该覆盖移动构造函数,它不再是微不足道的(尝试在上面添加一个正确的移动 ctor 和is_trivially_move_constructible)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-13
    • 1970-01-01
    • 1970-01-01
    • 2010-12-03
    • 1970-01-01
    相关资源
    最近更新 更多