You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++移动构造函数调用规则及不使用std::move触发移动构造的方法

现象原因

你遇到的情况是C标准规定的复制消除(Copy Elision) 优化导致的,这一优化在C17及之后的标准中是强制要求的,更早的C++标准中也是编译器普遍支持的可选优化。
你代码中的MyString s1(MyString("test"));属于典型的可复制消除场景:MyString("test")是同类型的纯右值,用来初始化s1时,编译器会直接将临时对象的内存分配在s1的地址上,相当于跳过了临时对象构造+移动/拷贝构造的两步流程,直接执行一次const char*构造函数完成s1的初始化,因此不会触发移动构造。

补充说明

你贴出的代码存在笔误:类定义的类名是MyString,但后续构造函数的实现写的是String::String,实际开发时需要修正保证类名一致,否则会编译失败。

不使用std::move触发移动构造的方法

方法1:关闭GCC的复制消除优化

GCC提供了编译参数-fno-elide-constructors用来禁用复制消除优化,你在编译时加上该参数即可看到预期的两行输出:

g++ your_code.cpp -fno-elide-constructors -o test

关闭优化后,编译器会严格按照你预想的流程执行:先构造临时纯右值,再调用移动构造函数初始化s1。

方法2:构造不可复制消除的右值场景

C++17的强制复制消除仅对纯右值直接初始化同类型对象的场景生效,你可以调整代码逻辑,将参数改为非纯右值的右值(亡值),就能避免被优化掉移动构造,例如:

// 示例:通过返回函数参数的方式生成亡值
MyString pass(MyString s) {
    return s;
}

int main() {
    MyString s1(pass(MyString("test")));
    return 0;
}

这种场景下返回的s是亡值,不符合强制复制消除的条件,编译器会优先调用移动构造函数完成初始化,不需要额外加std::move。

内容的提问来源于stack exchange,提问作者Touki Liu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 21:09:01