c++ - "Overload" function template based on function object operator() signature -
consider example of function template takes function reference first argument. overloaded based on function signature of first argument. body of each overload feeds 1st argument function appropriately it's signature.
template<typename t> struct mapttot { typedef t (type)(const t); }; template<typename t> std::vector<t> map_vec( const typename mapttot<t>::type& fnc, const std::vector<t>& source) { std::vector<t> dest; dest.reserve(source.size()); (const auto : source) { dest.emplace_back(fnc(i)); } return dest; } template<typename t> struct maptandvectot { typedef t (type)(const t, const std::vector<t>&); }; template<typename t> std::vector<t> map_vec( const typename maptandvectot<t>::type& fnc, const std::vector<t>& source) { std::vector<t> dest; dest.reserve(source.size()); (const auto : source) { dest.emplace_back(fnc(i, source)); } return dest; }
because of overload, reference either of these functions can passed 1st arg:
int foo(const int x); int bar(const int x, const std::vector<int>& v);
and doing transparent:
const auto = map_vec(foo, v); const auto b = map_vec(bar, v);
the overloading strategy used above won't work function objects since object doesn't have signature per se. suppose function objects of interest following.
class addnum { public: addnum(const int num) : num_(num) {} int operator()(const int x) const { return x + num_; } private: const int num_; }; class addnummulsize { public: addnummulsize(const int num) : num_(num) {} int operator()(const int x, const std::vector<int>& v) const { return (x + num_) * v.size(); } private: const int num_; };
how can change function templates accept both function objects , functions , overload based on how call should made?
specifically, want compile:
const addnum add2(2); const auto c = map_vec(add2, v); const addnummulsize add2mulsz(2); const auto d = map_vec(add2mulsz, v);
the error message clang gives quite clear , matches expect.
error: no matching function call 'map_vec'
candidate function [with t = int] not viable: no known conversion 'const addnum' 'typename mapttot::type &' (aka 'int (&)(const int)') 1st argument
update: c++98 version of question
“overload” function template based on function object operator() signature in c++98
change signature generically take function object of type f
, can use expression-sfinae restrict overloads based on f
can called with:
template<typename f, typename t> auto map_vec(f&& fnc, const std::vector<t>& source) -> decltype(void(fnc(std::declval<t>())), std::vector<t>{}); template<typename f, typename t> auto map_vec(f&& fnc, const std::vector<t>& source) -> decltype(void(fnc(std::declval<t>(), source)), std::vector<t>{});
Comments
Post a Comment