Редактировать : путь C ++ 0x можно найти в конце.
Редактировать 2 : Я тупой, и способ Более короткий путь C ++ 98/03, чем все эти черты, можно найти в конце ответа.
Если вы хотите, чтобы ваша функция работала для любого контейнера произвольной стандартной библиотеки, вам нужно вытащить какой-нибудь шаблонОружие.
Дело в том, что разные контейнеры принимают разное количество параметров шаблона.Например, std::vector
, std::deque
и std::list
: 2: базовый тип элемента T
и тип распределителя Alloc
.std::set
и std::map
, с другой стороны, принимают 3 и 4 соответственно: оба имеют тип ключа K
, map принимает другой тип значения V
, затем оба принимают тип компаратора Compare
и тип распределителя Alloc
.Вы можете получить обзор всех типов контейнеров, предоставляемых стандартной библиотекой, например, здесь .
Теперь для шаблонных пистолетов.Мы будем использовать частично специализированные метаструктуры признаков, чтобы получить базовый тип элемента.(Я использую class
вместо typename
из чистого предпочтения.)
template<class T>
struct ContainerTraits;
// vector, deque, list and even stack and queue (2 template parameters)
template<
template<class, class> class Container,
class T, class Other
>
struct ContainerTraits< Container<T,Other> >{
typedef T value_type;
};
// for set, multiset, and priority_queue (3 template parameters)
template<
template<class, class, class> class Container,
class T, class Other1, class Other2
>
struct ContainerTraits< Container<T,Other1,Other2> >{
typedef T value_type;
};
// for map and multimap (4 template parameters)
template<
template<class, class, class, class> class Container,
class Key, class T, class Other1, class Other2
>
struct ContainerTraits< Container<Key,T,Other1,Other2> >{
typedef Container<Key,T,Other1,Other2> ContainerT;
// and the map returns pair<const Key,T> from the begin() function
typedef typename ContainerT::value_type value_type;
};
Теперь, когда подготовка завершена, перейдем к функции get_front
!
template<class Container>
typename ContainerTraits<Container>::value_type
get_front(Container const& c){
// begin() is the only shared access function
// to the first element for all standard container (except std::bitset)
return *c.begin();
}
Уф!И это все!Полный пример можно увидеть на Ideone .Конечно, можно было бы уточнить это еще дальше, вплоть до возврата фактического значения, сопоставленного с ключом в std::map
, или использовать функции доступа, специфичные для контейнера, но мне было немного лень это делать,: P
Редактировать
A way Более простой способ C ++ 0x - использование нового синтаксиса функции конечного возврата, из которогопример можно найти здесь на Ideone .
Edit 2
Ну, я не знаю почему, но я совершенно не думалвложенных typedef
с при написании этого ответа.Я оставлю подробный путь в качестве справочника для классов признаков / паттернов, соответствующих шаблону. Это способ сделать это, в основном то же самое, что я делал с классами черт, но в конечном итоге менее многословно.