假设我有
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)更整齐地写出这个,最好是一行?
答案 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);
}