Well, as explained in the previous remarks, the compiler cannot deduce the container type of the iterator given as the parameter of Sum.
However, it is possible to use the fact that std::map<X,Y>::iterator::value_type is a pair of values std::pair<XX, YY>. Of course, this would not limit the desired specializing of Sum to std::map iterators, but to any container iterator returning a pair of element (eg. std::vector< std::pair<std::string, double> >.)
If this does not bother you, or if sthg like std::vector< std::pair<std::string, double> > should use the same specialization, then the following code seems to give the desired results in your case:
#include <map>
#include <string>
#include <iostream>
#include <cassert>
#include <boost/utility/enable_if.hpp>
#include <boost/type_traits/remove_reference.hpp>
// a small structure to
template <class U>
struct is_a_key_pair_it
{
typedef boost::false_type type;
};
template <class A, class B>
struct is_a_key_pair_it< std::pair<A, B> >
{
typedef boost::true_type type;
};
// using boost::disable_if to avoid the following code to be instanciated
// for iterators returning a std::pair
template <typename T>
const double Sum(T start_iter, T end_iter,
typename boost::disable_if<
typename is_a_key_pair_it<
typename boost::remove_reference<typename T::value_type>::type
>::type >::type * dummy = 0)
{
// code...
std::cout << "non specialized" << std::endl;
return 0;
}
// using boost::enable_if to limit the following specializing of Sum
// to iterators returning a std::pair
template <typename T>
const double Sum(T start_iter, T end_iter,
typename boost::enable_if<
typename is_a_key_pair_it<
typename boost::remove_reference<typename T::value_type>::type
>::type >::type * dummy = 0)
{
// different code...
std::cout << "specialized" << std::endl;
return 1;
}
int main()
{
typedef std::map<std::string, double> map_t;
// check
assert(is_a_key_pair_it<map_t::iterator::value_type>::type::value);
// works also for const_iterators
assert(is_a_key_pair_it<map_t::const_iterator::value_type>::type::value);
map_t test_map;
test_map["Line1"] = 10; // add some data
test_map["Line2"] = 15;
double ret = Sum(test_map.begin(),test_map.end());
}