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

时间:2012-07-21 05:14:14

标签: c++ boost c++03 boost-lambda

假设我有

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)更整齐地写出这个,最好是一行?

2 个答案:

答案 0 :(得分:6)

没有

Boost.Lambda在处理重载运算符时效果最佳。一旦你将一个命名函数调用带入事物中,Boost.Lambda在使代码更简洁和易于阅读方面变得不那么有用了。你必须开始使用功能绑定器和其他类似的东西。

你使用lambda参数作为索引(而不是被索引的值)这一事实可能会使得在Boost.Lambda库中使用operator []更加困难。

可以制作一个与此相当的Boost.Lambda。但它不会是我称之为“整洁”的东西,而“1行”将极其长。

有一个原因可以解释为什么C ++ 11将lambda引入语言而不是将Boost.Lambda合并到标准库中。

哦,不要忘记:Boost.Lambda通常被认为是过时的。请改用Boost.Phoenix。当然,它不会比Lambda更能帮助你。

答案 1 :(得分:3)

使用Boost.Phoenix(这是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);
}