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

为何std::make_unique可接受左值Foo对象创建unique_ptr?

为什么std::make_unique<Foo>(Foo_obj)能用左值参数编译?

你这里的核心误解是把std::make_unique的参数当成了仅接受右值引用,但实际上它用的是万能引用(universal references),不是单纯的右值引用。

让我拆解一下:

  • std::make_unique的声明大概是这样的:

    template<typename T, typename... Args>
    std::unique_ptr<T> make_unique(Args&&... args);
    

    这里的Args&&...是万能引用,它的特性是会根据传入的实参类型自动推导:如果传的是左值,就推导成左值引用;如果传的是右值,就推导成右值引用。

  • 当你传入左值Foo_obj时,Args会被推导为const Foo&(或者Foo&,取决于Foo的构造函数定义),make_unique内部会调用Foo的拷贝构造函数(比如Foo(const Foo&))来创建对象副本,然后把这个副本的所有权交给unique_ptr。

  • 你之前以为它只接受右值,可能是混淆了万能引用和右值引用。只有当模板参数是固定类型时,T&&才是右值引用,比如void func(Foo&&),这时候只能传右值;但template<typename T> void func(T&&)就是万能引用,能同时接受左值和右值。

举个实际场景:如果你的Foo类有默认生成的拷贝构造函数,那么auto pointer = make_unique<Foo>(Foo_obj)完全合法,它就是在创建Foo_obj的拷贝,然后用unique_ptr管理这个拷贝的生命周期。如果想调用移动构造函数,你才需要用std::move(Foo_obj)把左值转成右值,这时候make_unique会调用Foo(Foo&&)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 17:29:06