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

如何正确将unique_ptr传入Lambda并传递该Lambda至其他函数?

Lambda持有unique_ptr并传递给function时的编译错误解决

原代码

#include <memory>
#include <string>
#include <iostream>
#include <functional>

using namespace std;

void call(function<void()>&& f) {
    f();
}

int main()
{
    auto ptr = make_unique<string>("hello\n");
    auto fn = [ptr = move(ptr)] () { cout << *ptr; };
    call(move(fn));
    return 0;
}

编译错误

error: use of deleted function ‘main()::<lambda()>::<lambda>(const main()::<lambda()>&)’
error: use of deleted function ‘std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = std::__cxx11::basic_string<char>; _Dp = std::default_delete<std::__cxx11::basic_string<char> >]’

错误原因

std::function要求存储的可调用对象必须是可拷贝构造的,但你的Lambda捕获了std::unique_ptr——这是一个独占所有权的智能指针,拷贝构造函数被显式删除。Lambda会因为捕获了不可拷贝的成员,自身的拷贝构造函数也被隐式删除,导致std::function无法完成拷贝操作,触发编译错误。

解决方法

方法1:使用C++20的std::move_only_function(推荐)

std::move_only_function是C++20引入的,专门用于存储仅可移动的可调用对象,完美适配持有unique_ptr的Lambda:

#include <memory>
#include <string>
#include <iostream>
#include <functional>

using namespace std;

void call(move_only_function<void()>&& f) {
    f();
}

int main()
{
    auto ptr = make_unique<string>("hello\n");
    auto fn = [ptr = move(ptr)] () { cout << *ptr; };
    call(move(fn));
    return 0;
}

方法2:改用std::shared_ptr(兼容C++11及以上)

如果需要兼容C++17及更早版本,可将unique_ptr替换为shared_ptr——它支持拷贝操作,通过引用计数管理所有权,这样Lambda的拷贝构造函数就能正常生成:

#include <memory>
#include <string>
#include <iostream>
#include <functional>

using namespace std;

void call(function<void()>&& f) {
    f();
}

int main()
{
    auto ptr = make_shared<string>("hello\n");
    auto fn = [ptr] () { cout << *ptr; };
    call(move(fn));
    return 0;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 23:01:34