I have a method like this
template<typename T, typename U> map<T,U> mapMapValues(map<T,U> old, T (f)(T,U)) { map<T,U> new; for(auto it = old.begin(); it != old.end(); ++it) { new[it->first] = f(it->first,it->second); } return new; }
and the idea is that you'd call it like this
BOOST_AUTO_TEST_CASE(MapMapValues_basic) { map<int,int> test; test[1] = 1; map<int,int> transformedMap = VlcFunctional::mapMapValues(test, [&](int key, int value) -> int { return key + 1; } ); }
However I get the error: no instance of function template "VlcFunctional::mapMapValues" matches the argument list argument types are: (std::map, std::allocator>>, __lambda1)
Any idea what I'm doing wrong? Visual Studio 2008 and Intel C++ compiler 11.1
Syntax. Simply put, a lambda function is just like any normal python function, except that it has no name when defining it, and it is contained in one line of code. A lambda function evaluates an expression for a given argument. You give the function a value (argument) and then provide the operation (expression).
Just like a normal function, a Lambda function can have multiple arguments with one expression. In Python, lambda expressions (or lambda forms) are utilized to construct anonymous functions. To do so, you will use the lambda keyword (just as you use def to define normal functions).
In Python, a lambda function is a single-line function declared with no name, which can have any number of arguments, but it can only have one expression. Such a function is capable of behaving similarly to a regular function declared using the Python's def keyword.
If you are passing an instance of a class as a parameter, you must specify the class name or the object class as a parameter to hold the object. In Java, there is no type for lambda expression. Instead, it would help if you used an interface, i.e., a functional interface, to accept the parameter.
Your function is expecting a function pointer, not a lambda.
In C++, there are, in general, 3 types of "callable objects".
If you want to be able to use all of these in your function interface, then you could use std::function
:
template<typename T, typename U> map<T,U> mapMapValues(map<T,U> old, std::function<T(T, U)> f) { ... }
This will allow the function to be called using any of the three types of callable objects above. However, the price for this convenience is a small amount of overhead on invokations on the function (usually a null pointer check, then a call through a function pointer). This means that the function is almost certainly not inlined (except maybe with advanced WPO/LTO).
Alternatively, you could add an additional template parameter to take an arbitrary type for the second parameter. This will be more efficient, but you lose type-safety on the function used, and could lead to more code bloat.
template<typename T, typename U, typename F> map<T,U> mapMapValues(map<T,U> old, F f)
Your parameter type declaration T (f)(T,U)
is of type 'free function taking a T
and a U
and returning a T
'. You can't pass it a lambda, a function object, or anything except an actual function with that signature.
You could solve this by changing the type of the parameter to std::function<T(T,U)>
like this:
template<typename T, typename U> map<T,U> mapMapValues(map<T,U> old, std::function<T(T,U)>) { }
Alternately, you could declare the function type as a template argument like this:
template<typename T, typename U, typename Fn> map<T,U> mapMapValues(map<T,U> old, Fn fn) { fn(...); }
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