能否用指定初始化器配合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++版本和语法细节:
不可行的写法说明
你期望的std::make_unique<MyStruct>{...}写法编译不过。因为std::make_unique是函数模板,函数调用必须用圆括号(),这里的大括号{}会被编译器解析为试图直接构造std::unique_ptr对象,而unique_ptr的构造函数不支持这种指定初始化器形式,所以会报错。可行的优雅写法(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
相关产品推荐
相关产品推荐

