3

假设我有

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)更简洁地写这个,最好是在 1 行中?

4

2 回答 2

6

不。

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

而且您使用 lambda 参数作为索引(而不是被索引的值)这一事实可能会在 Boost.Lambda 库中使用 operator[] 时搞砸了。

可以制作与此等效的 Boost.Lambda。但这不会是我称之为“整洁”的任何东西,而且“1 行”会非常长。

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

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

于 2012-07-21T05:41:56.360 回答
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);
}
于 2012-07-21T05:51:25.597 回答