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; });
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).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With