Lambda作为类成员起作用

Lambda functions as class members

本文关键字:成员 起作用 Lambda      更新时间:2023-10-16

是否有可能接受两种不同类型的lambda函数作为类成员而事先不知道它们的模板参数?

struct two_functors {
    std::function<???> a;
    std::function<???> b;
    ...
};

使得这样的事情成为可能:

void main(){
    vector<two_functors> many_functors;
    int a = 2;
    int b = 3;
    double c = 4.7;
    double d = 8.4;
    two_functors add_and_subtract;
    add_and_subtract.a = [a, b](int x, int y){cout << x + y << endl;};
    add_and_subtract.b = [c, d](double x, double y){cout << x - y << endl;};
    two_functors multiply_and_divide;
    multiply_and_divide.a = [c, d](double x, double y){cout << x * y << endl;};
    multiply_and_divide.b = [a, b](int x, int y){cout << x / y << endl;};
    many_functors.push_back(add_and_subtract);
    many_functors.push_back(multiply_and_divide);
    for (auto functors : many_functors){
        functors.a();
        functors.b();
    }
}

如果您只想在不同的时间构造two_functors,但稍后按顺序一次执行它们,则可以使用捕获的数据。

struct two_functors
{
    function<void ()> a;
    function<void ()> b;
};
int main()
{
    vector<two_functors> many_functors;
    int a = 2;
    int b = 3;
    double c = 4.7;
    double d = 8.4;
    two_functors add_and_subtract {
        [a, b](){cout << a + b << endl;},
        [c, d](){cout << c - d << endl;}
    };
    two_functors multiply_and_divide {
        [c, d](){cout << c * d << endl;},
        [a, b](){cout << a / b << endl;}
    };
    many_functors.push_back(add_and_subtract);
    many_functors.push_back(multiply_and_divide);
    for (auto functors : many_functors){
        functors.a();
        functors.b();
    }
}

这实际上是一个元组。你可以看到这个接口是如何实现的。

template< class F0, class F1 >
struct two_functors {
   F0 func0;
   F1 func1;
};
template< class F0, class F1 >
two_functors<F0, F1> make_two_functor( F0&& f0, F1&& f1 )
{ 
   // Added [std::forward][2]
   return two_functors<F0,F1>( std::forward<F0>(f0), std::forward<F1>(f1) ); 
}

不是试图回答(我只是需要格式化技巧),只是Steven的建议的一个变化

template<typename A, typename B> 
two_functors<A,B> make_two_functors(A&& a, B&& b) {
   return two_functors<A,B> {a, b};
}

与使用std::forward<T>相比,这有什么缺点吗?

Btw -我希望c++ 11不再需要这样的"maker"

Steven的答案的另一种选择是使用中间的"保护伞"类。

编辑:刚刚在g++ (GCC) 4.5.3上编译了一个例子

 #include <functional>
 #include <iostream>
 using namespace std;
 class myfunction
 {
 };
 template <typename T>
 class specificFunction : public myfunction
 {
     public:
     function<T> f;
     specificFunction(function<T> pf)
     {
         f = pf;
     }
 };
 struct two_functors {
     myfunction* a;
     myfunction* b;
 };

int main()
{
     myfunction* f = new specificFunction<void(int,int)> ([](int a, int b) { cout << a << " - " << b << endl; });
     myfunction* f2 = new specificFunction<void(double,int)> ([](double a, int b) { cout << a << " - " << b << endl; });
     two_functors tf;
     tf.a = f;
     tf.b = f2;
     ((specificFunction<void(int,int)>*)(tf.a))->f(4,5);
     ((specificFunction<void(double,int)>*)(tf.b))->f(4.02,5);
 }