Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using lambdas in template class

I'm trying to use a template class with a lambda function parameter. However, I don't understand how to pass the parameter. Here's what I've tried so far:

#include <iostream>
using namespace std;

template <class F>
class A {
public:

   int f(int i)
   {
       return F(i); //*
   }
};

int main(int argc, const char * argv[]) {
auto f = [](int i){return i+5;};
A<decltype(f)> a;
cout << a.f(5);
return 0;
}

I get an error in the marked line.

Can someone help?

like image 500
Ofer Magen Avatar asked Sep 03 '16 16:09

Ofer Magen


Video Answer


1 Answers

Your example doesn't work because F is a type, not a callable object. The next step is to instantiate it by creating a member variable.

template <class F>
class A {
    F function;
public:
    int f(int i) {
         return function(i);
    }
};

However, that still won't work because lambda default constructors are deleted. That means we need another way to construct function. That can be achieved by passing an argument to A's constructor.

template<typename F>
class A {
    F function;
public:
    A(const F& f) : function(f) {}
    int f(int i) {
        return function(i);
    }
};

// ...

auto f = [](int i) { return i+5; };
A<decltype(f)> a(f);

This uses the lambda copy constructor, which isn't deleted.

Live example

If you want it to work with any lambda, you can add some more magic.

template<typename F>
class A {
    F function;

public:
    A(const F& f) : function(f) {}

    template<typename ...Args>
    auto f(Args... args) -> std::result_of_t<F(Args...)> {
        return function(std::forward<Args>(args)...);
    }
};

Live example

like image 93
Nelfeal Avatar answered Oct 11 '22 02:10

Nelfeal