Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Instantiating C++ lambda by its type

Tags:

I want a way to make functor from function. Now I trying to wrap function call by lambda function and instantiate it later. But compiler says than lambda constructor is deleted. So is there any way to compile this code ? Or maybe another way for that ?

#include <iostream>  

void func()
{
    std::cout << "Hello";
}

auto t = []{ func(); };
typedef decltype(t) functor_type;

template <class F>
void functor_caller()
{
    F f;
    f();
}

int main()
{
    functor_caller<functor_type>();
    return 0;
}

Now I get such compiler error:

error: use of deleted function  '<lambda()>::<lambda>()'

error: a lambda closure type has a deleted default constructor

In my opinion the only way is to use macro:

#define WRAP_FUNC(f) \
struct f##_functor       \
{                       \
    template <class... Args >                             \
    auto operator()(Args ... args) ->decltype(f(args...)) \
    {                                                     \
        return f(args...);                                \
    }                                                     \
};

then

WRAP_FUNC(func);

and then (in main)

functor_caller<func_functor>()
like image 832
andigor Avatar asked Jun 17 '12 16:06

andigor


1 Answers

The code doesn't make sense. Imagine you have a capturing lambda like this:

{
    int n = 0;
    auto t = [&n](int a) -> int { return n += a; };
}

What could it possibly mean to default-construct an object of type decltype(t)?

As @Matthieu suggests, you could wrap the lambda into a function object:

std::function<int(int)> F = t;

Or you could template your call-site directly on the type of the lambda (or any callable entity):

template <typename F>
int compute(int a, int b, F f)
{
    return a * f(b);  // example
}

Usage: int a = 0; for (int i : { 1, 3, 5 }) { a += compute(10, i, t); }

If at all possible, the second style is preferable, since the conversion to std::function is a non-trivial, potentially expensive operation, as is the actual function call through the resulting object. However, if you need to store a uniform collection of heterogeneous callable entities, then std::function may well be the easiest and most convenient solution.

like image 154
Kerrek SB Avatar answered Sep 20 '22 07:09

Kerrek SB