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

调用自定义split_partition函数时,为何需使用const lambda?

为什么用非const引用Lambda调用split_partition会编译失败?

我实现了一个基于std::partition_copy的模板函数split_partition,用来根据谓词把容器元素分割到原容器和目标容器中,代码如下:

template<class Container, class Predicate>
void split_partition(Container& src, Container& dest, Predicate p)
{
    auto ends = std::partition_copy(
        std::make_move_iterator( src.begin() ), std::make_move_iterator( src.end() ),
        src.begin(), std::back_inserter(dest), p
    ); 

    src.erase(ends.first, src.end());
}

我用以下方式调用时编译失败:

split_partition(a, b, [](auto& t) {return t.i > 4; });

但把Lambda参数改成const引用后就能正常编译:

split_partition(a, b, [](const auto& t) {return t.i > 4; });

补充说明:测试用的容器定义为

std::vector<Thing> a = { {0, "foo"}, {1, "bar"}, {5, "what"}, {8, "yo"}, {2, ""} };
std::vector<Thing> b;

原因分析

问题核心在于std::make_move_iterator的特性:它返回的迭代器解引用后得到的是右值引用(准确来说,std::move_iterator的operator*会返回std::move(*base),也就是右值)。

你最初使用的Lambda参数auto&是非const左值引用,而C++语法明确禁止非const左值引用绑定到右值上,这直接导致编译报错。

当把Lambda参数改为const auto&后,const左值引用是可以绑定到右值的(这是C++标准特性,用于延长临时对象的生命周期),此时谓词能正常接收std::move_iterator解引用后的右值,编译自然通过。

另外补充:你用std::make_move_iterator来移动元素以避免拷贝开销的思路本身没问题,但要注意谓词参数的类型必须匹配移动迭代器产生的值类别。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 13:22:47