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

能否用指定初始化器配合std::make_unique创建std::unique_ptr?

问题:能否用指定初始化器配合std::make_unique创建std::unique_ptr?

给定结构体定义:

struct MyStruct
{
  int my_number;
  std::string my_string;
};

想知道能不能用指定初始化器配合std::make_unique创建std::unique_ptr,比如用下面这种写法:

// 期望的写法
auto my_struct = std::make_unique<MyStruct>{.my_number = 4, .my_string = "two"};
// 而非这种按顺序传参的写法
auto my_struct = std::make_unique<MyStruct>(4, "two");

目前已经能通过new创建对象再传给std::unique_ptr构造函数实现,但这种写法不够优雅:

auto my_struct = std::unique_ptr<MyStruct>(new MyStruct{.my_number = 4, .my_string = "two"});

回答

可以实现,但要注意C++版本和语法细节:

  1. 不可行的写法说明
    你期望的std::make_unique<MyStruct>{...}写法编译不过。因为std::make_unique是函数模板,函数调用必须用圆括号(),这里的大括号{}会被编译器解析为试图直接构造std::unique_ptr对象,而unique_ptr的构造函数不支持这种指定初始化器形式,所以会报错。

  2. 可行的优雅写法(C++20及以上)
    在C++20及更高版本中,你可以通过传递一个用指定初始化器构造的临时MyStruct对象给std::make_unique,写法如下:

auto my_struct = std::make_unique<MyStruct>(MyStruct{.my_number = 4, .my_string = "two"});

这种写法既保留了指定初始化器的清晰性,又沿用了std::make_unique的安全性(避免直接用new带来的潜在内存泄漏风险),比你当前用new的写法更优雅可靠。

另外,利用C++20的聚合初始化特性,还可以省略类名,直接用双层大括号传递初始化器(可读性稍差但更简洁):

auto my_struct = std::make_unique<MyStruct>({.my_number = 4, .my_string = "two"});

这种写法的本质是让make_unique内部用聚合初始化的方式构造MyStruct对象,同样符合要求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 21:45:41