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

向std::list中emplace std::unique_ptr出现编译错误,求解决方法

问题:将std::unique_ptr放入std::list时出现编译错误

编译错误信息

<source>:29:23: error: no matching function for call to 'std::__cxx11::list<std::unique_ptr<test> >::emplace(std::remove_reference<std::unique_ptr<test>&>::type)'
   29 |     mapList[1].emplace(std::move(t));

相关代码

using namespace std;

class test {
public:
    int i;
};

typedef std::list<std::unique_ptr<test>> testList;
int main() {
    unordered_map<int, testList> mapList;
    mapList.try_emplace(1, testList());
    std::unique_ptr<test> t = make_unique<test>();
    mapList[1].emplace(std::move(t));

    return 0;
}

解决方案

错误根源是误用了std::list::emplace函数:

  • std::list::emplace的第一个参数必须是插入位置的迭代器(比如list.end()),后续参数才是构造元素所需的参数;
  • 如果你想直接在list尾部添加已有的std::unique_ptr(通过移动语义),应该使用emplace_back或push_back,这两个函数不需要指定位置参数。

修改后的代码(两种可选方式)

方式1:使用emplace_back

using namespace std;

class test {
public:
    int i;
};

typedef std::list<std::unique_ptr<test>> testList;
int main() {
    unordered_map<int, testList> mapList;
    mapList.try_emplace(1, testList());
    std::unique_ptr<test> t = make_unique<test>();
    mapList[1].emplace_back(std::move(t)); // 替换emplace为emplace_back

    return 0;
}

方式2:使用push_back

// ... 其余代码与原代码一致
mapList[1].push_back(std::move(t));

两者的区别:emplace_back是就地构造元素(这里用右值引用构造unique_ptr),push_back是移动构造元素,对于unique_ptr来说最终效果一致。

如果确实需要在指定位置插入元素,可以给emplace传递迭代器参数,比如:

mapList[1].emplace(mapList[1].begin(), std::move(t));

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 02:20:23