Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I return a lambda object?

I want to return a lambda object from a function without casting it to a function pointer or function object. More specifically, I want to leave it to the client to decide whether or not to cast to a function object or retain the lambda as an anonymous function:

template<typename F> // F may be a std::function, boost::function, or lambda object
auto func(F f) -> decltype(???) // what do I put in here?
{
    return [=]()
    {
        return f(someParameter);
    }
}

This code doesn't work because I don't know what type to deduce. One option might be to copy the body of the lambda into the decltype call. Surely there is a better way!

My reasoning for wanting to do it this way is that I want to leave open the possibility of the compiler more intelligently inlining or unwrapping the lambdas. Does this reasoning make sense? If so, why, and when is it better simply to return std::function? Could this method ever be slower at compile time?

like image 612
quant Avatar asked Apr 03 '14 02:04

quant


People also ask

How do I return in lambda?

Here the expression is nothing but the result returned by the lambda function. Lambda functions are syntactically restricted to return a single expression. You can use them as an anonymous function inside other functions. The lambda functions do not need a return statement, they always return a single expression.

Can lambda have a return type?

The return type of a lambda expression is automatically deduced. You don't have to use the auto keyword unless you specify a trailing-return-type. The trailing-return-type resembles the return-type part of an ordinary function or member function.

Will lambda function return a function object?

What are lambda functions? A lambda function is a small, anonymous function that take any number of arguments but only have one expression. Lambda functions return an object that is assigned to a variable or used as a part of other functions.

Can lambda statements return a value?

The lambda must contain the same number of parameters as the delegate type. Each input parameter in the lambda must be implicitly convertible to its corresponding delegate parameter. The return value of the lambda (if any) must be implicitly convertible to the delegate's return type.


1 Answers

In C++11 you cannot do this. You can do a few things that are close to it, but not this.

Basically, the only way to extract a type of a C++11 lambda is to deduce it from an instance of the type, and you cannot name the type in an unevaluated context. So a function cannot return a type whose type depends on the type of a lambda. (Unless said lambda is declared, with body, prior to the function's declaration, which is not useful in this case). You can write a functor that is a manual function object, or use std::bind which does that for you.

You can have it evaluate some other functor you also pass in with the lambda, but that gets awkward (especially in C++11 where such functors either have to type erase, or have to be an old-school functor written "manually" as a struct or class).

One of the features added in C++1y makes it easy, however:

template<typename F, typename T>
auto func(F f, T t) {
  return [=]() {
    return f(t);
  };
}
int main() {
  auto f = func( [](int x){ std::cout << x << "\n"; }, 7 );
  f();
  f();
}

Live example

It is possible your compiler already has C++1y support for this feature.

like image 112
Yakk - Adam Nevraumont Avatar answered Oct 02 '22 21:10

Yakk - Adam Nevraumont