I have simple map implementation and simple id (identity):
template <typename T>
T map(const T& x, std::function<decltype(x[0])(decltype(x[0]))> f) {
T res(x.size());
auto res_iter = begin(res);
for (auto i(begin(x)); i < end(x); ++i) {
*res_iter++ = f(*i);
}
return res;
}
template <typename T>
T id(T& x) {return x;}
and when I call is as
vector<int> a = {1,2,3,4,5,6,7,8,9};
map(a, id<const int>);
it works, but I want call it without type specification, like this:
map(a, id);
and when I do it, I get error:
error: cannot resolve overloaded function 'id' based on conversion to type 'std::function<const int&(const int&)>'
map(a, id);
^
How can I resolve it and why can't compiler deduce type of id from its context in map when error contains right bounded type?
If you are in a C++14 compliant environment, there is a very clean way to do this. Instead of using std::function and a templated class, use an unconstrained forwarding reference and a generic lambda as follows:
#include <vector>
template <typename T,typename F>
T map(const T& x, F &&f) {
T res(x.size());
auto res_iter = begin(res);
for (auto i(begin(x)); i < end(x); ++i) {
*res_iter++ = f(*i);
}
return res;
}
auto id = [](auto x) { return x;};
int main()
{
std::vector<int> v = {1, 2, 3, 4};
auto v2 = map(v, id);
}
In C++11, you would have to replace the generic lambda with a functor whose operator() is a templated method, as follows:
struct {
template<typename T>
T operator()(T x) const
{
return x;
}
} id;
In C++98 syntax you will not be able to use the forwarding reference, so you will have to consider copying and functor mutability issues.
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