如何使用Boost(Lambda?)使std::sort()更容易

How to use Boost (Lambda?) to make std::sort() easier?

本文关键字:更容易 std sort 何使用 Boost Lambda      更新时间:2023-10-16

假设我有

struct Value { int foo(); };
size_t *begin = ...,
       *end   = ...;

如果我想在C++03中对一堆Value索引进行排序,我必须写一些乏味的东西:

struct Comparator
{
    Value *data;
    Comparator(Value *data) : data(data) { }
    bool operator()(size_t a, size_t b)
    { return data[a].foo() < data[b].foo(); }
};
sort(begin, end, Comparator(data));

有没有办法用Boost(也许用Boost.Lambda)更巧妙地写这篇文章,最好是一行?

否。

Boost.Lambda在处理过载操作员时效果最好。一旦你将命名函数调用引入到事物中,Boost.Lambda在使代码更加简洁易读方面就变得不那么有用了。你必须开始使用函数绑定器和其他类似的东西。

事实上,您使用lambda参数作为索引(而不是正在索引的值)可能会把事情搞砸,甚至在BoostLambda库中也使用了运算符[]。

可以做出类似的Boost.Lambda。但它不会是我称之为"整洁"的东西,"1行"会非常长。

C++11在语言中引入Lambda,而不是仅仅将Boost.Lambda合并到标准库中,这是有原因的。

哦,别忘了:Boost。Lambda通常被认为是过时的。使用Boost.Phoenix。当然,它不会像Lambda那样对你有任何帮助。

使用Boost.Fenix(Boost的首选lambda库):

#include <boost/phoenix/phoenix.hpp>
{
    // for bind and ref
    using namespace boost::phoenix;
    using namespace boost::phoenix::placeholders;
    std::sort(begin, end
              , bind(&Value::foo, ref(data)[arg1]) < bind(&Value::foo, ref(data)[arg2]) );
}

另一种选择是使用LocalFunction,它本质上允许您以可移植的方式执行正在执行的操作(将本地类型传递给std::sort,这对于C++03是不允许的)。用法应该是(代码未经测试):

#include <boost/local_function.hpp>
{
    int BOOST_LOCAL_FUNCTION(const bind& data, std::size_t lhs, std::size_t rhs)
    {
        return data[lhs].foo() < data[rhs].foo();
    } BOOST_LOCAL_FUNCTION_NAME(comparator)
    std::sort(begin, end, comparator);
}