Разница между вашими двумя шаблонами функций не в разнице между ассоциативными контейнерами и последовательностями, а в части хранимого типа.
Чтобы уточнить, std::set
является ассоциативным контейнером, но будет работать с вашей printSequence
функцией; проблема с map
не в том, что она ассоциативна, а в том, что value_type
является pair
и вас интересует только часть second
.
Самое простое, что нужно сделать - это абстрагировать операцию разыменования.
например. используется так:
#include <map>
#include <vector>
template< class X, class Y >
void test( const std::map<X, Y>& mp )
{
printEither( mp.begin(), mp.end(), MakeMapDerefence( mp ) );
}
template< class Y >
void test( const std::vector<Y>& vec )
{
printEither( vec.begin(), vec.end(), MakeSimpleDereference( vec ) );
}
Определяется следующим образом (есть довольно большая часть плиты котла, которая, вероятно, является однострочной надстройкой):
template< class ReferenceType, class IteratorType >
struct SimpleDereference
{
ReferenceType operator() ( IteratorType i ) const
{
return *i;
}
};
template< class ReferenceType, class IteratorType >
struct MapDereference
{
ReferenceType operator() ( IteratorType i ) const
{
return i->second;
}
};
// Helper template function to make an appropriate SimpleDerefence instance
template< class Container >
SimpleDereference< typename Container::const_reference
, typename Container::const_iterator >
MakeSimpleDereference( const Container& )
{
return SimpleDereference< typename Container::const_reference
, typename Container::const_iterator >();
}
// Helper template function to make an appropriate SimpleDerefence instance
template< class Container >
SimpleDereference< typename Container::reference
, typename Container::iterator >
MakeSimpleDereference( Container& )
{
return SimpleDereference< typename Container::reference
, typename Container::iterator >();
}
// Helper template function to make an appropriate MapDerefence instance
template< class Container >
MapDereference< const typename Container::mapped_type&
, typename Container::const_iterator >
MakeMapDerefence( const Container& )
{
return MapDereference< const typename Container::mapped_type&
, typename Container::const_iterator >();
}
// Helper template function to make an appropriate MapDerefence instance
template< class Container >
MapDereference< typename Container::mapped_type&
, typename Container::iterator >
MakeMapDereference( Container& )
{
return MapDereference< typename Container::mapped_type&
, typename Container::iterator >();
}
#include <iostream>
#include <ostream>
template <class Iterator, class Dereference> void printEither(Iterator begin, Iterator end, Dereference deref)
{
for (; begin != end; ++begin)
{
std::cout << deref(begin);
}
}