I have the following snippet of code, that although entirely trivial, illustrates a pattern I am trying to use in more general code.
template<typename InT, typename ResT>
ResT unary_apply( InT val, std::function<ResT(InT)> fn )
{
return fn(val);
}
I would like to be able to call unary_apply with function pointers, functors, lambdas etc: hence the use of std::function
to abstract that all away.
When I try to use the above in the following way, C++ (g++ 4.7) is unable to perform the relevant type inference:
double blah = unary_apply( 2, []( int v ) { return 3.0 * v; } );
Failing with
src/fun.cpp:147:75: error: no matching function for call to ‘unary_apply(int, test()::<lambda(int)>)’
src/fun.cpp:147:75: note: candidate is:
src/fun.cpp:137:6: note: template<class InT, class ResT> ResT unary_apply(InT, std::function<ResT(InT)>)
src/fun.cpp:137:6: note: template argument deduction/substitution failed:
src/fun.cpp:147:75: note: ‘test()::<lambda(int)>’ is not derived from ‘std::function<ResT(double)>’
And I find that I have to explicitly specify the template parameters (in practice I believe it is just the return type that is not inferable):
double blah = unary_apply<int, double>( 2, []( int v ) { return 3.0 * v; } );
I am not that familiar with the type inference rules in C++11, but the above behaviour does seem reasonable (I can see that inferring via the internal mechanics of std::function
is probably rather a big ask). My question is: is it possible to re-write the unary_apply
function above to keep the same flexibility (in terms of the types of functions/functors etc that can be passed as a second parameter) whilst also giving more of a clue to type inference so I do not have to explicitly supply the template parameters at the point of call?
Lambda Functions in C++11 - the Definitive Guide. A lambda function is a function that you can write inline in your source code (usually to pass in to another function, similar to the idea of a functor or function pointer ). With lambda, creating quick functions has become much easier, and this means that not only can you start using lambda...
Under the final C++11 spec, if you have a lambda with an empty capture specification, then it can be treated like a regular function and assigned to a function pointer. Here's an example of using a function pointer with a capture-less lambda:
When you capture by reference, the lambda function is capable of modifying the local variable outside the lambda function--it is, after all, a reference. But this also means that if you return a lamba function from a function, you shouldn't use capture-by-reference because the reference will not be valid after the function returns.
Lambda function was briefly introduced in C++11 Thread 1. Creating Threads. In this section, we'll see the usefulness of lambda function for multi-threading. Let's start from where we left: We're going to create 5 more threads, and put those into std::vector container. For the join (), we'll use for_each (): Output should look like this:
Going bit more duck-typey should work:
template <typename T, typename F>
auto unary_apply(T&& val, F&& func) -> decltype(func(val)) {
return func(std::forward<T>(val));
}
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