MoveInsertable 和 CopyInsertable 之间的区别?

2022-01-17 00:00:00 compiler-construction c++ c++11

有人可以对这两个术语提供更清晰的解释吗?

Can someone provide a more lucid explanation of these two terms?

换句话说,请用例子做一些简单的解释.

In other words, some simple explanation with an example, please.

(来自:cppreference.com)

(from : cppreference.com)

MoveInsertable : 指定一个类型的右值可以复制到未初始化的存储中.

MoveInsertable : Specifies that a rvalue of the type can be copied in uninitialized storage.

CopyInsertable :指定一个实例type 可以在未初始化的存储中就地复制构造.

CopyInsertable : Specifies that an instance of the type can be copy-constructed in-place, in uninitialized storage.

推荐答案

这些需求是类型 T 和容器 X 之间的关系.容器有一个分配器类型,A,用于为其包含的对象分配内存.

These requirements are a relationship between a type T and a container X. A container has an allocator type, A, which it uses to allocate the memory for its contained objects.

如果 m 是这些分配器之一,pT*rvrv 类型的右值code>T 和 v 类型为 T 的表达式:

If m is one of these allocators, p a T*, rv an rvalue of type T, and v an expression of type T:

  1. CopyInsertable 由标准定义:

T is CopyInsertable into X 表示下面的表达式是良构的:

T is CopyInsertable into X means that the following expression is well-formed:

allocator_traits<A>::construct(m, p, v);

  • MoveInsertable 由标准定义:

    T is MoveInsertable into X 表示下面的表达式是良构的:

    T is MoveInsertable into X means that the following expression is well-formed:

    allocator_traits<A>::construct(m, p, rv);
    

  • 现在要理解这些定义,我们必须知道 allocator_traits<A>::construct 做了什么.很简单,在这种情况下它调用:

    Now to understand these definitions, we must know what allocator_traits<A>::construct does. Quite simply, in this case it calls:

    m.construct(p, v) // CopyInsertable case
    m.construct(p, rv) // MoveInsertable case
    

    vrv 在这里仍然有各自的值类别,因为 std::forward 应用于 allocator_traits<A>::construct.

    v and rv still have their respective value categories here because std::forward is applied to the argument of allocator_traits<A>::construct.

    那么分配器的construct 成员函数有什么作用呢?好吧,正如你所料,它在 p 位置构造了一个 T 类型的对象,方法是:

    So what does an allocators construct member function do? Well, as you might expect, it constructs an object of type T at the location p by doing:

    ::new ((void*)p) T(v) // CopyInsertable case
    ::new ((void*)p) T(rv) // MoveInsertable case
    

    同样,vrvstd::forwarded.

    Again, v and rv are std::forwarded.

    当然,它们会分别调用复制或移动构造函数.

    Of course, these will invoke the copy or move constructors respectively.

    所以:

    1. T is CopyInsertable into X:X的分配器可以放置-new 构造 T 的元素,传递 T
    2. 类型的表达式
    3. T is MoveInsertable into X:X的分配器可以放置-new 构造 T 的元素,传递 T
    4. 类型的右值
    1. T is CopyInsertable into X: the allocator for X can placement-new construct an element of T, passing an expression of type T
    2. T is MoveInsertable into X: the allocator for X can placement-new construct an element of T, passing an rvalue of type T

    相关文章