Я хотел бы знать, можно ли создать реальный объект функтора из лямбда-выражения. Я так не думаю, но если нет, то почему?
Чтобы проиллюстрировать, приведенный ниже код сортирует точки с использованием различных политик для координат 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. Это легко понять, и я не уверен, что действительно хочу использовать здесь лямбда-выражения.
Но если бы я захотел заменить 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
. Это предполагает, что С++ 0x позволяет безымянному типу лямбды вообще быть аргументом шаблона, я не знаю. - person Steve Jessop   schedule 26.01.2011operator()
. В общем случае для этого требуется экземпляр, потому что именно там хранятся любые захваченные переменные, и я не уверен, определяется ли каким-либо образом лямбда без захвата как особый случай. В частности, есть ли у его типа доступный конструктор без аргументов, который вы использовали? - person Steve Jessop   schedule 26.01.2011XOrder()(lhs.x, rhs.x)
, вы вызываете конструктор без аргументовXOrder
(ну, или другой конструктор, все параметры которого являются необязательными), а затем вызываетеoperator()
для результирующего временного объекта. Я не знаю, потому что я не смотрел, можете ли вы просто создать экземпляр лямбды из ее типа. - person Steve Jessop   schedule 26.01.2011