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

如何排序unique_ptr列表?现有代码因拷贝构造函数删除编译失败

你的推测完全正确!std::unique_ptr的拷贝构造函数确实被显式删除了——这正是你代码编译失败的根源。

咱们来拆解一下问题:你写的ptrLess函数参数是按值传递的unique_ptr<int>,这意味着调用这个函数时会尝试拷贝传入的unique_ptr,但unique_ptr是独占所有权的智能指针,设计上就不允许拷贝(否则会出现多个指针指向同一块内存,析构时重复释放的问题),所以编译器直接抛出了那个删除函数的错误。

接下来给你几种可行的解决方案,都能实现unique_ptr列表的排序:

方案1:修改比较函数为引用传递

把比较函数的参数改成const左值引用,这样就不会触发拷贝,只是引用原有的unique_ptr对象:

bool ptrLess(const unique_ptr<int>& ptr1, const unique_ptr<int>& ptr2) {
    return *ptr1 < *ptr2;
}

这样调用list.sort(ptrLess)时,只会传递引用,完全不会涉及拷贝操作,完美避开了删除的拷贝构造函数。

方案2:使用lambda表达式(更简洁)

不需要单独定义比较函数,直接在sort调用里写lambda,同样用引用参数:

myList.sort([](const unique_ptr<int>& a, const unique_ptr<int>& b) {
    return *a < *b;
});

这种方式更紧凑,也符合现代C++的写法。

额外注意:容器插入时的移动语义

另外你原来的代码里还有个小坑:变量名用了list,这会和std::list冲突,建议改成myList这类名字。而且往列表里push_back的时候,也需要用std::move来转移unique_ptr的所有权,否则同样会触发拷贝错误:

myList.push_back(std::move(ptr1));
myList.push_back(std::move(ptr2));
myList.push_back(std::move(ptr3));

完整可编译代码

把这些修改整合后,完整代码如下:

#include <iostream>
#include <list>
#include <memory>

using namespace std;

bool ptrLess(const unique_ptr<int>& ptr1, const unique_ptr<int>& ptr2) {
    return *ptr1 < *ptr2;
}

int main() {
    unique_ptr<int> ptr1(new int(3));
    unique_ptr<int> ptr2(new int(2));
    unique_ptr<int> ptr3(new int(5));
    list<unique_ptr<int>> myList;

    myList.push_back(std::move(ptr1));
    myList.push_back(std::move(ptr2));
    myList.push_back(std::move(ptr3));

    myList.sort(ptrLess);
    // 或者用lambda:myList.sort([](const auto& a, const auto& b) { return *a < *b; });

    for (auto &element : myList) {
        cout << *element << " ";
    }
    return 0;
}

运行这段代码会输出2 3 5,完全符合预期。

至于你提到的移动构造函数——其实我们在push_back的时候已经用到了,排序本身不需要移动unique_ptr的所有权,只需要访问它们指向的值,所以用引用传递比较函数参数是最直接高效的方案。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 07:14:26