使用lambda函数进行向量排序,当不在同一范围内时如何传递变量来捕获组?

Posted

技术标签:

【中文标题】使用lambda函数进行向量排序,当不在同一范围内时如何传递变量来捕获组?【英文标题】:Vector sorting with lambda function, how to pass in variable to capture group when not in the same scope? 【发布时间】:2020-08-26 17:29:23 【问题描述】:

基本上我有一个相当大的 lambda 函数来对自定义对象的向量进行排序。唯一的问题是 lambda 函数依赖于通过捕获组传递给它的对象。这已经有一段时间了,但是现在我想在程序的不同部分重用相同的函数。这是我的代码的样子:

void fun(int i) 
...

BarMovement movement(i);

auto sortByBarMovement = [movement](OrderLogic::OpenOrder const& order1, OrderLogic::OpenOrder const& order2) -> bool

    ...
;

std::sort(std::begin(same_bar_order_fill), std::end(same_bar_order_fill), sortByBarMovement);

...


我想将 sortByBarMovement lambda 移动到它自己的函数中,以便我可以重用它。但是它依赖于捕获组中的项目movement

如果我将 sortByBarMovement 移动到不同的范围,如何在 C++ 中将此 movement 对象传递给 lambda 函数?

【问题讨论】:

移动是指std::move lambda,还是修改源代码以将lambda 的逻辑放入命名函数? @FrançoisAndrieux lambda 的逻辑到一个命名函数中。谢谢 为什么不简单地写一个函数而不是 lambda? 您的 lambda 是有状态的,它有一个内部状态(捕获的 movement 对象),您可以同时拥有多个具有不同状态的 sortByBarMovement 实例。这对于函数是不可能的,您需要某种对象来管理可能的状态。您不能创建函数的实例,它们不是对象,因此它们不能具有 BarMovement 的关联实例,除非通过参数传递它们。但这会改变签名。只有无状态的 lambda 可以轻松转换为函数。 将它移动到类似 sort_with_bar_movement(const BarMovement& bm, std::vector& to_sort) 的函数中,并在其中调用 std::sort ,同时引用您的移动对象跨度> 【参考方案1】:

lambda 只是函子的语法糖。一大优点是您可以在相同的范围内直接在您使用它的地方编写 lambdas。另一方面,如果你想在其他地方重用它,与普通函数对象相比,lambda 并没有太大的优势。如果你不加糖可能会更清楚:

struct sortByBarMovement_type 
    BarMovement movement;
    sortByBarMovement_type(const BarMovement& movement) : movement(movement) 
    bool operator()(OrderLogic::OpenOrder const& order1, OrderLogic::OpenOrder const& order2) const 
        ...
    
;

这基本上就是你所需要的。 fun 现在看起来像这样:

void fun(int i) 
...

BarMovement movement(i);

sortByBarMovement_type sortByBarMovementmovement;

std::sort(std::begin(same_bar_order_fill), std::end(same_bar_order_fill), sortByBarMovement);

...

PS:我试图尽可能接近您的代码。这就是我复制movement 的原因。也许保留参考就足够了。此外,您的 lambdas operator()constsortByBarMovement_type::operator() 不一定是 const

【讨论】:

【参考方案2】:

您可以创建一个类来保留对BarMovement 的引用并实现operator() 以进行比较:

struct sortByBarMovement 
    sortByBarMovement(const BarMovement& bm) : bmref(bm) 

    bool operator()(const OrderLogic::OpenOrder& order1,
                    const OrderLogic::OpenOrder& order2) const
    
        // logic ...
        return <result>;
    

    const BarMovement& bmref;
;

std::sort(std::begin(same_bar_order_fill),
          std::end(same_bar_order_fill), sortByBarMovement(movement));

【讨论】:

以上是关于使用lambda函数进行向量排序,当不在同一范围内时如何传递变量来捕获组?的主要内容,如果未能解决你的问题,请参考以下文章

C++ 函数返回一个向量/字符串,但不是一个数组

分段错误:C++ 使用 lambda 比较器对字符串向量进行排序

网络。同一个 lambda 向量的不同结果,取决于它是通过 glmnet 计算还是作为参数传递下来

使用 std::sort 对包含两个数据成员的对象向量进行排序

使用 O(m) 空间在 O(n) 时间内对向量<int>(n) 进行排序?

访问算法的 lambda 函数中的迭代器导致我出现分段错误