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

为何类成员unique_ptr的移动构造函数未被调用?

含std::unique_ptr成员的类移动构造问题分析与解决

问题原因

编译错误的核心在于:右值引用参数本身是左值。

在你的移动构造函数C(C&& other): s(other.s) {}中,虽然other是C&&类型的右值引用,但other作为有名字的变量,它本身属于左值。直接访问other.s得到的是std::unique_ptr<S>&类型的左值,此时编译器会尝试调用std::unique_ptr已被删除的拷贝构造函数,而非预期的移动构造函数——这和你在code-1中必须用std::move(s1)将左值转为右值才能触发移动构造的逻辑完全一致。

修复方案

有两种简洁有效的修复方式:

方案1:用std::move转换成员为右值

在初始化std::unique_ptr成员时,通过std::move将other.s转为右值,触发std::unique_ptr的移动构造:

#include <memory>

struct S {};

class C
{
    private:
        std::unique_ptr<S> s = nullptr;
    public:
        C(C&& other): s(std::move(other.s)) {} // 添加std::move转换右值
        C() = default;
};

int main()
{
    C c1;
    C c2(std::move(c1));
}

方案2:让编译器自动生成移动构造函数

当类包含不可拷贝但可移动的成员(如std::unique_ptr)时,编译器会自动生成正确的默认移动构造函数,只要你没有手动定义拷贝构造/拷贝赋值操作。直接默认移动构造函数即可,无需手动实现:

#include <memory>

struct S {};

class C
{
    private:
        std::unique_ptr<S> s = nullptr;
    public:
        C() = default;
        C(C&&) = default; // 让编译器自动生成移动构造
};

int main()
{
    C c1;
    C c2(std::move(c1));
}

编译器生成的默认移动构造会对每个成员执行移动操作,完全符合需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.02 01:53:10