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"; } }
Comments
Post a Comment