未知类型下如何初始化tuple中存储的智能指针
问题原因
- 核心错误在于
ptr.reset( {} )的写法:给reset传入空花括号会构造空指针作为参数,执行后unique_ptr仍然不持有任何对象,和你注释里预期的new T()效果完全相反。 - 原始代码中
struct A、struct B的定义末尾缺少分号,属于语法错误,无法正常编译。
解决方案
你需要先从unique_ptr的类型中拿到它指向的元素类型,再创建对应类型的实例。std::unique_ptr内置了类型别名element_type可以直接拿到指向的类型,配合折叠表达式即可完成全部元素的初始化:
#include <tuple> #include <memory> #include <functional> #include <cassert> struct A { int a = 1; }; struct B { int b = 2; }; int main() { std::tuple<std::unique_ptr<A>, std::unique_ptr<B>> my_tuple; std::apply([] (auto&... ptr) { // 方式1:用reset配合new完成初始化 (..., ptr.reset(new typename std::decay_t<decltype(ptr)>::element_type{})); }, my_tuple); // 验证初始化结果 assert(std::get<0>(my_tuple) != nullptr); assert(std::get<0>(my_tuple)->a == 1); assert(std::get<1>(my_tuple) != nullptr); assert(std::get<1>(my_tuple)->b == 2); // 更推荐的方式:用std::make_unique替代new,异常安全性更好 std::apply([] (auto&... ptr) { (..., ptr = std::make_unique<typename std::decay_t<decltype(ptr)>::element_type>()); }, my_tuple); return 0; }
上述代码中std::decay_t<decltype(ptr)>是为了去掉ptr的引用属性,拿到纯std::unique_ptr<T>类型,再取element_type即可得到T。
内容的提问来源于stack exchange,提问作者AreN
相关产品推荐
相关产品推荐

