c++26新功能—平凡迁移

发布于:2025-07-02 ⋅ 阅读:(17) ⋅ 点赞:(0)

一、平凡迁移

Trivially Relocatable,平凡迁移。大家不要被这些名词给唬住。只要弄明白了平凡就明白了平凡迁移,在前面的文章中对平凡和POD数据进行了分析说明,大家可以看一看,简单的理解就是只有基础的数据类型(当然这不准确)数据或数据集合。而平凡迁移就可以理解成使用直接的内存进行来处理对象的内存,即使用类似memcpy的方式直接复制对象的内存进行处理,从而避免调用相关的构造函数等。这样做的好处当然是减少了调用流程,提高了内存的应用效率。
注意,对于Trivially来说,这里指的是Relocatable,要与Copyable区别开来。

二、应用说明

平凡迁移的提到了迁移,说明对象从源地址被拷贝到指定目标地址后,源对象的生命周期结束,而目标地址的新对象开始生命周期,所以叫做迁移,即对象的生命周期从源转移到了目标地址。需要说明的是,在这个过程中,是不需要调用析构函数和构造函数的。这个有点类似于C语言中的结构体数据直接拷贝的过程。
平凡迁移的限定条件为(截取相关英文文档):
Extend the Properties of classes section (11.2 [class.prop]) by adding new properties:

  1. A class C is default-movable if

overload resolution for direct-initializing an object of type C from an xvalue of type C selects a constructor that is a direct member of C and is neither user-provided nor deleted,
overload resolution for assigning to an lvalue of type C from an xvalue of type C selects an assignment operator function that is a direct member of C and is neither user-provided nor deleted, and
C has a destructor that is neither user-provided nor deleted.
2. A class is eligible for trivial relocation unless it

has any virtual base classes,
has a base class that is not a trivially relocatable class,
has a non-static data member of an object type that is not of a trivially relocatable type, or
has a deleted destructor,
except that it is implementation-defined whether an otherwise-eligible union having one or more subobjects of polymorphic class type is eligible for trivial relocation.

  1. A class C is a trivially relocatable class if it is eligible for trivial relocation and

has the trivially_relocatable_if_eligible class-property-specifier,
is a union with no user-declared special member functions, or
is default-movable.
4. [Note W: A class with const-qualified or reference non-static data members can be trivially relocatable. —end note]

  1. A class C is eligible for replacement unless

it has a base class that is not a replaceable class,
it has a non-static data member that is not of a replaceable type,
overload resolution fails or selects a deleted constructor when direct-initializing an object of type C from an xvalue of type C (9.4.1 [dcl.init.general]),
overload resolution fails or selects a deleted assignment operator function when assigning to an lvalue of type C from an xvalue of type C (7.6.19 [expr.ass] and 12.4.3.2 [over.ass]), or
it has a deleted destructor.
6. A class C is a replaceable class if it is eligible for replacement and

has the replaceable_if_eligible class-property-specifier,
is a union with no user-declared special member functions, or
is default-movable.
7. [Note X: Accessibility of the special member functions is not considered when establishing trivial relocatability or replaceability. —end note]

  1. [Note Y: Not all trivially copyable classes are trivially relocatable or replaceable. —end note]
    其实简单总结一下即为:
  2. 具备平凡移动构造
  3. 具备平凡析构
  4. 无虚基类,成员和基类均为平凡迁移类型(平凡的传染性)
    说明一下,其与前面提到的Trivially Copyable的不同在于其拷贝构造函数不同,Trivially Copyable要求其也必须为平凡的。另外,在某些场景下,平凡迁移可能退化到move语义。更详细的需要等待标准的最终落地 。

三、例程

看一下相关文档及官网上的例程:

struct Empty {};

static_assert(    is_trivially_copyable_v<X>);
static_assert(    is_trivially_relocatable_v<X>);
static_assert(    is_replaceable_v<X>);


struct Non-Trivial {
   // Implementation details are elided.
   // Non-Trivial is neither trivially copyable, trivially relocatable, nor replaceable.
];

static_assert(not is_trivially_copyable_v<X>);
static_assert(not is_trivially_relocatable_v<X>);
static_assert(not is_replaceable_v<X>);


struct Immobile {
   Immobile(Immobile&&) = delete;
   Immobile& operator=(Immobile&&) = delete;

   Immobile() = default;
};

static_assert(not is_trivially_copyable_v<X>);
static_assert(    is_trivially_relocatable_v<X>);
static_assert(not is_replaceable_v<X>);

更详细的可以参看“p2786r13”提案文档。

四、总结

标准的演进一个重要的方向是打通应用孤岛的桎梏,扩展功能的应用场景。从一开始只处理平凡的数据类型,到后来出现复杂的对象会有专门的处理方式(如拷贝函数等),而最终大家可能发现所谓复杂的对象处理底层仍然是对内存的处理,所以,能不能够直接使用基础的平凡数据的处理方式呢?
C++26的新标准给了答案,当然,这种把内存处理方式打通的过程肯定是一个逐渐发展的过程,所以大家要仔细看清其应用的范围以及其在出现异常的情况下如何进行处理。这也为大家开发程序时遇到类似的问题提供了一个解决方案。


网站公告

今日签到

点亮在社区的每一天
去签到