【发布时间】:2011-01-26 10:34:13
【问题描述】:
我想知道是否可以从 lambda 表达式创建一个实际的仿函数对象。我不这么认为,但如果不是,为什么?
为了说明,给定下面的代码,它使用 x 和 y 坐标的各种策略对点进行排序:
#include <vector>
#include <functional>
#include <algorithm>
#include <iostream>
struct Point
{
Point(int x, int y) : x(x), y(y) {}
int x, y;
};
template <class XOrder, class YOrder>
struct SortXY :
std::binary_function<const Point&, const Point&, bool>
{
bool operator()(const Point& lhs, const Point& rhs) const
{
if (XOrder()(lhs.x, rhs.x))
return true;
else if (XOrder()(rhs.x, lhs.x))
return false;
else
return YOrder()(lhs.y, rhs.y);
}
};
struct Ascending { bool operator()(int l, int r) const { return l<r; } };
struct Descending { bool operator()(int l, int r) const { return l>r; } };
int main()
{
// fill vector with data
std::vector<Point> pts;
pts.push_back(Point(10, 20));
pts.push_back(Point(20, 5));
pts.push_back(Point( 5, 0));
pts.push_back(Point(10, 30));
// sort array
std::sort(pts.begin(), pts.end(), SortXY<Descending, Ascending>());
// dump content
std::for_each(pts.begin(), pts.end(),
[](const Point& p)
{
std::cout << p.x << "," << p.y << "\n";
});
}
表达式std::sort(pts.begin(), pts.end(), SortXY<Descending, Ascending>()); 按x 值降序排序,然后y 值升序排序。这很容易理解,我不确定我是否真的想在这里使用 lambda 表达式。
但是如果我想用 lambda 表达式替换 Ascending / Descending,你会怎么做?以下无效:
std::sort(pts.begin(), pts.end(), SortXY<
[](int l, int r) { return l>r; },
[](int l, int r) { return l<r; }
>());
【问题讨论】:
-
可能你需要一个
make_sortXY函数来推断模板参数?见make_pair。这是假设 C++0x 完全允许 lambda 的无名类型作为模板参数,我不知道。 -
同样,一个 lambda 表达式会产生一个带有
operator()的 object。一般来说,它需要实例,因为这是保留任何捕获的变量的地方,而且我不确定是否以任何方式将无捕获 lambda 定义为特殊情况。特别是,它的类型是否具有您使用过的可访问的无参数构造函数? -
@Steve:感谢您的 cmets。我明白你的意思,除了你第二条评论中的最后一句话。你指的是什么?
-
当您编写
XOrder()(lhs.x, rhs.x)时,您正在调用XOrder的无参数构造函数(嗯,或者其他参数都是可选的构造函数),然后在生成的临时函数上调用operator()目的。我不知道,因为我没有查过,你是否可以从它的类型中实例化一个这样的 lambda。 -
@Steve:我猜不是,因为你无法获得 lambda 的类型。