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>{}); 

demo


Comments

Popular posts from this blog

python - mat is not a numerical tuple : openCV error -

c# - MSAA finds controls UI Automation doesn't -

wordpress - .htaccess: RewriteRule: bad flag delimiters -