Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When defining a function, what type is a lambda function/expression?

Tags:

c++

c++11

lambda

I want to define a function that takes (besides its usual input arguments) a lambda function. And I want to restrict that function as far as possible (its own input- and return types).

int myfunc( const int a, LAMBDA_TYPE (int, int) -> int mylamda )
{
    return mylambda( a, a ) * 2;
}

Such that I can call the function as follows:

int input = 5;
myfunc( input, [](int a, int b) { return a*b; } );

What is the correct way to define myfunc?

And is there a way to define a default lambda? Like this:

int myfunc( const int a, LAMBDA_TYPE = [](int a, int b) { return a*b; });
like image 580
S.H Avatar asked Sep 27 '26 19:09

S.H


1 Answers

If you take a std::function<int(int,int)> it will have overhead, but it will do what you want. It will even overload correctly in C++14.

If you do not want type erasure and allocation overhead of std::function you can do this:

template<
  class F,
  class R=std::result_of_t<F&(int,int)>,
  class=std::enable_if_t<std::is_same<int,R>{}>
>
int myfunc( const int a, F&& f )

or check convertability to int instead of sameness. This is the sfinae solution. 1

This will overload properly. I used some C++14 features for brevity. Replace blah_t<?> with typename blah<?>::type in C++11.

Another option is to static_assert a similar clause. This generates the best error messages.

Finally you can just use it: the code will fail to compile if it cannot be used the way you use it.

In C++1z concepts there will be easier/less code salad ways to do the sfinae solution.


1 On some compilers std::result_of fails to play nice with sfinae. On those, replace it with decltype(std::declval<F&>()(1,1)). Unless your compiler does not support C++11 (like msvc 2013 and 2015) this will work. (luckily 2013/3015 has a nice result_of).

like image 138
Yakk - Adam Nevraumont Avatar answered Sep 29 '26 10:09

Yakk - Adam Nevraumont



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!