前の説明で説明したように、コンパイラは のパラメーターとして指定された反復子のコンテナーの型を推測できませんSum
。
std::map<X,Y>::iterator::value_type
ただし、値のペアであるという事実を使用することは可能ですstd::pair<XX, YY>
。もちろん、これは の目的の特殊化Sum
をstd::map
イテレータに制限するのではなく、要素のペアを返す任意のコンテナ イテレータ (例: . std::vector< std::pair<std::string, double> >
)に制限します。
これが気にならない場合、または sthg likestd::vector< std::pair<std::string, double> >
が同じ特殊化を使用する必要がある場合、次のコードはあなたの場合に望ましい結果をもたらすようです:
#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());
}