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

能否将std::unique_ptr<T>指向的对象移入std::vector<T>且无额外副本?

问题描述

假设我有一个存储泛型T对象的vector:

std::vector<T> vector_of_ts = {...};

该vector本质上是底层堆分配的T对象数组。现在我有以下代码:

std::unique_ptr<T> t = std::make_unique<T>(...);

这同样是底层堆分配的T对象。是否可以通过移动操作将该对象推入vector,而不产生临时或额外副本?类似如下操作:

vector_of_ts.move(*t)
解决方案

当然可以实现无额外副本的转移,但你写的vector_of_ts.move(*t)不是标准用法,正确的做法分两种情况:

情况1:将unique_ptr指向的对象移动到vector

如果你想把unique_ptr管理的T对象移动到vector里,不需要额外拷贝,只需对*t执行移动构造,再手动置空unique_ptr避免重复释放:

vector_of_ts.emplace_back(std::move(*t));
t.reset(); // 必须手动置空,否则unique_ptr析构时会释放已转移到vector的对象

这里std::move(*t)会把*t转换成右值,触发T的移动构造函数(前提是T支持移动语义),vector会直接在自身堆内存中构造对象,无额外拷贝。

情况2:将unique_ptr本身存入vector

如果需要让vector存储unique_ptr<T>而非T对象,直接移动unique_ptr即可,这一操作仅转移指针所有权,完全无对象拷贝:

std::vector<std::unique_ptr<T>> vec_of_ptrs;
vec_of_ptrs.push_back(std::move(t));

注意事项

  • 第一种情况中必须调用t.reset(),否则unique_ptr仍持有原对象指针,生命周期结束时会尝试释放已属于vector的对象,引发双重释放错误。
  • 若T不支持移动语义(比如未定义移动构造函数且编译器无法生成默认版本),移动操作会退化为拷贝,此时无法避免拷贝行为。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 16:03:16