templates - How to overload function for different iterator value_types in C++ -


i want implement template function in c++ 11 takes pair of iterators. implementation should special processing if pair of iterators passed value type std::pair of arbitrary types. tried come following definitions:

// arbitrary value types template<typename iter> void process(iter begin, iter end) {     (iter iter = begin; iter != end; ++iter) {         std::cout << *iter << "\n";     } }  // std::pair value types template<typename iter, typename first, typename second,     typename std::enable_if<         std::is_same<             typename std::iterator_traits<iter>::value_type, std::pair<first,second>             >::value         >::type* = 0> void process(iter begin, iter end) {     (iter iter = begin; iter != end; ++iter) {         std::cout << (*iter).first << " " << (*iter).second << "\n";     } } 

using following example code:

std::vector<int> int_vec{{1,2,3,4}}; process(int_vec.begin(), int_vec.end()); 

correctly calls first definition of function process. however

std::vector<std::pair<int,std::string>> pair_vec{     {std::make_pair(1, "first"), std::make_pair(2, "second")}}; process(pair_vec.begin(), pair_vec.end()); 

also calls first definition , results in error message (using clang):

error: invalid operands binary expression ('ostream' (aka 'basic_ostream<char>') , 'std::__1::pair<int, std::__1::basic_string<char> >') 

why doesn't compiler pick second definition in case? how need change overloaded function?

the problem template arguments first , second can't deduced iter, argument subject template argument deduction, @ point @ require them in function signature.

you can, however, use iter deduce first , second using helper class (in below example ispair), , use template specialization there select between 2 options.

example:

template<typename t> struct ispair {     static const bool value = false; };  template<typename first, typename second> struct ispair<std::pair<first, second>> {     static const bool value = true; };  // arbitrary value types template<typename iter> void process(iter begin, iter end,               typename std::enable_if<                 !ispair<typename std::iterator_traits<iter>::value_type>::value              >::type* = 0) {     (iter iter = begin; iter != end; ++iter)      {         std::cout << *iter << "\n";     } }  // std::pair value types template<typename iter> void process(iter begin, iter end,               typename std::enable_if<                  ispair<typename std::iterator_traits<iter>::value_type>::value              >::type* = 0)  {     (iter iter = begin; iter != end; ++iter)      {         std::cout << (*iter).first << " " << (*iter).second << "\n";     } } 

working example on coliru


Comments