C++ 从lambda表达式创建函子

C++ 从lambda表达式创建函子,c++,lambda,c++11,functor,C++,Lambda,C++11,Functor,我想知道是否有可能从lambda表达式创建一个实际的函子对象。我不这么认为,但如果不是,为什么 为了进行说明,给出了下面的代码,该代码使用不同的x和y坐标策略对点进行排序: #include <vector> #include <functional> #include <algorithm> #include <iostream> struct Point { Point(int x, int y) : x(x), y(y) {}

我想知道是否有可能从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"; 
                  });
}
#包括
#包括
#包括
#包括
结构点
{ 
点(intx,inty):x(x),y(y){
int x,y;
};
模板
结构SortXY:
二进制函数
{
布尔运算符()(常量点和左侧、常量点和右侧)常量
{
if(XOrder()(lhs.x,rhs.x))
返回true;
else if(XOrder()(rhs.x,lhs.x))
返回false;
其他的
返回YOrder()(左侧,右侧);
}          
};
结构升序{bool操作符()(int l,int r)常量{return lr;};
int main()
{
//用数据填充向量
std::向量pts;
pts.推回(第(10,20)点);
pts.推回(第(20,5)点);
pts.推回(第(5,0)点);
pts.推回(第(10,30)点);
//排序数组
排序(pts.begin()、pts.end()、SortXY());
//转储内容
std::for_each(pts.begin()、pts.end(),
[](const Point&p)
{

std::cout出现此问题是因为SortXY只接受类型,而Lambda是对象。您需要重新编写它,以便它接受对象,而不仅仅是类型。这是函数对象的基本用法-请参阅如何
std::for_each
不接受类型,而是接受对象。

出现此问题是因为SortXY只接受类型,而lambdas是对象。您需要重新编写它,以便它接受对象,而不仅仅是类型。这是函数对象的基本用法-请参见
std::for_each
不接受类型,而是接受对象。

我在类中发布了一个类似的问题w.r.t.lambda functors。 看看这个,也许它有帮助:


我在类中发布了一个类似的问题w.r.t.lambda函子。 看看这个,也许它有帮助:


我遇到了一个类似的问题:在某些情况下需要提供一个“原始”函数指针,而在另一些情况下需要提供一个函子。因此,我想出了一个类似这样的“解决方法”:

template<class T>
class Selector
{
public:
    Selector(int (*theSelector)(T& l, T& r))
        : selector(theSelector) {}

    virtual int operator()(T& l, T& r) {
        return selector(l, r);
    }

    int (*getRawSelector() const)(T&, T&) {
        return this->selector;
    }

private:
    int(*selector)(T& l, T& r);
};
int
findMinWithFunctor(int* array, int size, Selector<int> selector)
{
    if (array && size > 0) {
        int min = array[0];
        for (int i = 0; i < size; i++) {
            if (selector(array[i], min) < 0) {
                min = array[i];
            }
        }
        return min;
    }
    return -1;
}

int 
findMinWithFunctionPointer(int* array, int size, int(*selector)(int&, int&))
{
    if (array && size > 0) {
        int min = array[0];
        for (int i = 0; i < size; i++) {
            if (selector(array[i], min) < 0) {
                min = array[i];
            }
        }
        return min;
    }
    return -1;
}
int numbers[3] = { 4, 2, 99 };

cout << "The min with functor is:" << findMinWithFunctor(numbers, 3, Selector<int>([](int& l, int& r) -> int {return (l > r ? 1 : (r > l ? -1 : 0)); })) << endl;


// or with the plain version
cout << "The min with raw fn-pointer is:" << findMinWithFunctionPointer(numbers, 3, Selector<int>([](int& l, int& r) -> int {return (l > r ? 1 : (r > l ? -1 : 0)); }).getRawSelector()) << endl;
template<class T>
class Selector
{
public:

    typedef int(*selector_fn)(T& l, T& r);

    Selector(selector_fn theSelector)
        : selector(theSelector) {}

    virtual int operator()(T& l, T& r) {
        return selector(l, r);
    }

    selector_fn getRawSelector() {
        return this->selector;
    }

private:
    selector_fn selector;
};
模板
类选择器
{
公众:
选择器(int(*选择器)(T&l、T&r))
:选择器(选择器){}
虚拟整数运算符()(T&l、T&r){
返回选择器(l,r);
}
int(*getRawSelector()常量)(T&,T&){
返回此->选择器;
}
私人:
内部(*选择器)(T&l、T&r);
};
假设您有两个非常简单的函数——如前所述——取函子或原始函数指针,如下所示:

template<class T>
class Selector
{
public:
    Selector(int (*theSelector)(T& l, T& r))
        : selector(theSelector) {}

    virtual int operator()(T& l, T& r) {
        return selector(l, r);
    }

    int (*getRawSelector() const)(T&, T&) {
        return this->selector;
    }

private:
    int(*selector)(T& l, T& r);
};
int
findMinWithFunctor(int* array, int size, Selector<int> selector)
{
    if (array && size > 0) {
        int min = array[0];
        for (int i = 0; i < size; i++) {
            if (selector(array[i], min) < 0) {
                min = array[i];
            }
        }
        return min;
    }
    return -1;
}

int 
findMinWithFunctionPointer(int* array, int size, int(*selector)(int&, int&))
{
    if (array && size > 0) {
        int min = array[0];
        for (int i = 0; i < size; i++) {
            if (selector(array[i], min) < 0) {
                min = array[i];
            }
        }
        return min;
    }
    return -1;
}
int numbers[3] = { 4, 2, 99 };

cout << "The min with functor is:" << findMinWithFunctor(numbers, 3, Selector<int>([](int& l, int& r) -> int {return (l > r ? 1 : (r > l ? -1 : 0)); })) << endl;


// or with the plain version
cout << "The min with raw fn-pointer is:" << findMinWithFunctionPointer(numbers, 3, Selector<int>([](int& l, int& r) -> int {return (l > r ? 1 : (r > l ? -1 : 0)); }).getRawSelector()) << endl;
template<class T>
class Selector
{
public:

    typedef int(*selector_fn)(T& l, T& r);

    Selector(selector_fn theSelector)
        : selector(theSelector) {}

    virtual int operator()(T& l, T& r) {
        return selector(l, r);
    }

    selector_fn getRawSelector() {
        return this->selector;
    }

private:
    selector_fn selector;
};
int
findMinWithFunctor(int*数组、int大小、选择器)
{
如果(数组和大小>0){
int min=数组[0];
对于(int i=0;i0){
int min=数组[0];
对于(int i=0;i
然后您可以这样调用此函数:

template<class T>
class Selector
{
public:
    Selector(int (*theSelector)(T& l, T& r))
        : selector(theSelector) {}

    virtual int operator()(T& l, T& r) {
        return selector(l, r);
    }

    int (*getRawSelector() const)(T&, T&) {
        return this->selector;
    }

private:
    int(*selector)(T& l, T& r);
};
int
findMinWithFunctor(int* array, int size, Selector<int> selector)
{
    if (array && size > 0) {
        int min = array[0];
        for (int i = 0; i < size; i++) {
            if (selector(array[i], min) < 0) {
                min = array[i];
            }
        }
        return min;
    }
    return -1;
}

int 
findMinWithFunctionPointer(int* array, int size, int(*selector)(int&, int&))
{
    if (array && size > 0) {
        int min = array[0];
        for (int i = 0; i < size; i++) {
            if (selector(array[i], min) < 0) {
                min = array[i];
            }
        }
        return min;
    }
    return -1;
}
int numbers[3] = { 4, 2, 99 };

cout << "The min with functor is:" << findMinWithFunctor(numbers, 3, Selector<int>([](int& l, int& r) -> int {return (l > r ? 1 : (r > l ? -1 : 0)); })) << endl;


// or with the plain version
cout << "The min with raw fn-pointer is:" << findMinWithFunctionPointer(numbers, 3, Selector<int>([](int& l, int& r) -> int {return (l > r ? 1 : (r > l ? -1 : 0)); }).getRawSelector()) << endl;
template<class T>
class Selector
{
public:

    typedef int(*selector_fn)(T& l, T& r);

    Selector(selector_fn theSelector)
        : selector(theSelector) {}

    virtual int operator()(T& l, T& r) {
        return selector(l, r);
    }

    selector_fn getRawSelector() {
        return this->selector;
    }

private:
    selector_fn selector;
};
整数[3]={4,2,99};
coutr?1:(r>l?-1:0));})l?-1:0));}).getRawSelector()选择器;
}
私人:
选择器\u fn选择器;
};

这里我们利用了一个简单的typedef来定义函数指针一次,只使用它的名称,而不是一遍遍地写声明。

我遇到了一个类似的问题:在某些情况下需要提供一个“原始”函数指针,而在另一些情况下需要提供一个函子。所以我想出了这样一个“解决办法”:

template<class T>
class Selector
{
public:
    Selector(int (*theSelector)(T& l, T& r))
        : selector(theSelector) {}

    virtual int operator()(T& l, T& r) {
        return selector(l, r);
    }

    int (*getRawSelector() const)(T&, T&) {
        return this->selector;
    }

private:
    int(*selector)(T& l, T& r);
};
int
findMinWithFunctor(int* array, int size, Selector<int> selector)
{
    if (array && size > 0) {
        int min = array[0];
        for (int i = 0; i < size; i++) {
            if (selector(array[i], min) < 0) {
                min = array[i];
            }
        }
        return min;
    }
    return -1;
}

int 
findMinWithFunctionPointer(int* array, int size, int(*selector)(int&, int&))
{
    if (array && size > 0) {
        int min = array[0];
        for (int i = 0; i < size; i++) {
            if (selector(array[i], min) < 0) {
                min = array[i];
            }
        }
        return min;
    }
    return -1;
}
int numbers[3] = { 4, 2, 99 };

cout << "The min with functor is:" << findMinWithFunctor(numbers, 3, Selector<int>([](int& l, int& r) -> int {return (l > r ? 1 : (r > l ? -1 : 0)); })) << endl;


// or with the plain version
cout << "The min with raw fn-pointer is:" << findMinWithFunctionPointer(numbers, 3, Selector<int>([](int& l, int& r) -> int {return (l > r ? 1 : (r > l ? -1 : 0)); }).getRawSelector()) << endl;
template<class T>
class Selector
{
public:

    typedef int(*selector_fn)(T& l, T& r);

    Selector(selector_fn theSelector)
        : selector(theSelector) {}

    virtual int operator()(T& l, T& r) {
        return selector(l, r);
    }

    selector_fn getRawSelector() {
        return this->selector;
    }

private:
    selector_fn selector;
};
模板
类选择器
{
公众:
选择器(int(*选择器)(T&l、T&r))
:选择器(选择器){}
虚拟整数运算符()(T&l、T&r){
返回选择器(l,r);
}
int(*getRawSelector()常量)(T&,T&){
返回此->选择器;
}
私人:
内部(*选择器)(T&l、T&r);
};
假设您有两个非常简单的函数——如前所述——取函子或原始函数指针,如下所示:

template<class T>
class Selector
{
public:
    Selector(int (*theSelector)(T& l, T& r))
        : selector(theSelector) {}

    virtual int operator()(T& l, T& r) {
        return selector(l, r);
    }

    int (*getRawSelector() const)(T&, T&) {
        return this->selector;
    }

private:
    int(*selector)(T& l, T& r);
};
int
findMinWithFunctor(int* array, int size, Selector<int> selector)
{
    if (array && size > 0) {
        int min = array[0];
        for (int i = 0; i < size; i++) {
            if (selector(array[i], min) < 0) {
                min = array[i];
            }
        }
        return min;
    }
    return -1;
}

int 
findMinWithFunctionPointer(int* array, int size, int(*selector)(int&, int&))
{
    if (array && size > 0) {
        int min = array[0];
        for (int i = 0; i < size; i++) {
            if (selector(array[i], min) < 0) {
                min = array[i];
            }
        }
        return min;
    }
    return -1;
}
int numbers[3] = { 4, 2, 99 };

cout << "The min with functor is:" << findMinWithFunctor(numbers, 3, Selector<int>([](int& l, int& r) -> int {return (l > r ? 1 : (r > l ? -1 : 0)); })) << endl;


// or with the plain version
cout << "The min with raw fn-pointer is:" << findMinWithFunctionPointer(numbers, 3, Selector<int>([](int& l, int& r) -> int {return (l > r ? 1 : (r > l ? -1 : 0)); }).getRawSelector()) << endl;
template<class T>
class Selector
{
public:

    typedef int(*selector_fn)(T& l, T& r);

    Selector(selector_fn theSelector)
        : selector(theSelector) {}

    virtual int operator()(T& l, T& r) {
        return selector(l, r);
    }

    selector_fn getRawSelector() {
        return this->selector;
    }

private:
    selector_fn selector;
};
int
findMinWithFunctor(int*数组、int大小、选择器)
{
如果(数组和大小>0){
int min=数组[0];
对于(int i=0;i0){
int min=数组[0];
对于(int i=0;i
然后您可以这样调用此函数:

template<class T>
class Selector
{
public:
    Selector(int (*theSelector)(T& l, T& r))
        : selector(theSelector) {}

    virtual int operator()(T& l, T& r) {
        return selector(l, r);
    }

    int (*getRawSelector() const)(T&, T&) {
        return this->selector;
    }

private:
    int(*selector)(T& l, T& r);
};
int
findMinWithFunctor(int* array, int size, Selector<int> selector)
{
    if (array && size > 0) {
        int min = array[0];
        for (int i = 0; i < size; i++) {
            if (selector(array[i], min) < 0) {
                min = array[i];
            }
        }
        return min;
    }
    return -1;
}

int 
findMinWithFunctionPointer(int* array, int size, int(*selector)(int&, int&))
{
    if (array && size > 0) {
        int min = array[0];
        for (int i = 0; i < size; i++) {
            if (selector(array[i], min) < 0) {
                min = array[i];
            }
        }
        return min;
    }
    return -1;
}
int numbers[3] = { 4, 2, 99 };

cout << "The min with functor is:" << findMinWithFunctor(numbers, 3, Selector<int>([](int& l, int& r) -> int {return (l > r ? 1 : (r > l ? -1 : 0)); })) << endl;


// or with the plain version
cout << "The min with raw fn-pointer is:" << findMinWithFunctionPointer(numbers, 3, Selector<int>([](int& l, int& r) -> int {return (l > r ? 1 : (r > l ? -1 : 0)); }).getRawSelector()) << endl;
template<class T>
class Selector
{
public:

    typedef int(*selector_fn)(T& l, T& r);

    Selector(selector_fn theSelector)
        : selector(theSelector) {}

    virtual int operator()(T& l, T& r) {
        return selector(l, r);
    }

    selector_fn getRawSelector() {
        return this->selector;
    }

private:
    selector_fn selector;
};
整数[3]={4,2,99};
可以吗?1:(r>l?-1:0));})l-1 : 0)); }).getRawSelector())选择器;
}
私人:
选择器\u fn选择器;
};

在这里,我们利用一个简单的typedef来定义函数指针一次,只使用它的名称,而不是反复编写声明。

您可能需要一个
make_sortXY
函数来推断模板参数?请参见
make\u pair
。这是假设C++0x允许匿名类型的lambda作为模板参数,我不知道。另外,lambda表达式会产生一个带有
操作符()的对象。一般来说,它需要实例,因为任何捕获的变量都保存在实例中,我不确定无捕获lambda是否以任何方式定义为特例。特别是,它的类型是否有您使用过的可访问的no-args构造函数?@Steve:thank's fo