#c #templates
#c #шаблоны
Вопрос:
Хорошо, я просто изучаю шаблоны. В любом случае, я, вероятно (определенно), делаю что-то не так, но вот в чем проблема:
Моя первая шаблонная функция объявлена следующим образом:
template<typename T>
std::ostreamamp; printFormatted(T constamp; container, std::ostreamamp; os = std::cout) {
//...
}
Затем я должен реализовать специализированный случай для карт, так что это то, что я пытался сделать:
template<>
std::ostreamamp; printFormatted<std::map<typename key, typename value>>(std::map<typename key, typename value> constamp; container, std::ostreamamp; os = std::cout) {
//...
}
Возможно, я допускаю ошибку со своими переменными ключа / значения, не уверен, но независимо от этого при попытке компиляции я получаю сообщение об ошибке:
error: wrong number of template arguments (1, should be 4)
error: provided for ‘template<class _Key, class _Tp, class _Compare, class _Allocator> class std::__debug::map’
Очевидно, что я чего-то не понимаю в шаблонах или картах? Кто-нибудь, пожалуйста, помогите?
Комментарии:
1. Есть
key
ли иvalue
фактические типы в вашем коде или вы намереваетесь использовать их в качестве заполнителей?
Ответ №1:
Предполагая, что вы используете key
и value
предназначены для размещения, вы не можете объявлять параметры шаблона встроенными с ключевым typename
словом. То Foo<typename T>
есть всегда недопустимо, но не следует ошибаться, Foo<typename T::bar>
что совсем другое. Синтаксис специализации выглядит следующим образом:
// Declare template parameters up front
template<typename Key, typename Value>
std::ostreamamp;
printFormatted<std::map<Key, Value> >(std::map<Key, Value> constamp; container, std::ostreamamp; os = std::cout);
но это не сработает, потому что это частичная специализация, и они не разрешены для шаблонов функций. Вместо этого используйте перегрузку:
template<typename Key, typename Value>
std::ostreamamp;
printFormatted(std::map<Key, Value> constamp; container, std::ostreamamp; os = std::cout);
Эта перегрузка будет предпочтительнее более общего шаблона.
Комментарии:
1. Это соответствует только картам с
less<K>
иstd::allocator
, хотя:-(2. Спасибо, это все исправило отлично!
Ответ №2:
То, что вы делаете, — это не полная специализация, а частичная специализация, поскольку у вас все еще есть шаблон, только более специализированный. Однако вы не можете частично специализировать функции, поэтому вместо этого мы просто предоставляем новую перегрузку. Для std::map
вам нужны четыре параметра шаблона (как подсказывает сообщение об ошибке):
template <typename K, typename V, typename Comp, typename Alloc>
std::ostream amp; printFormatted(const std::map<K,V,Comp,Alloc> amp; m,
std::ostream amp; o = std::cout)
{
// ...
}
Ответ №3:
Этот ответ не имеет отношения к C 11
Если вы используете компилятор до c 11, вы не можете использовать >>
при закрытии вложенных шаблонов. Вам нужен пробел между >
s.
C видит >>
токен, отличный >
от, и компилятор не использует его для закрытия шаблонов. Вам нужен пробел, чтобы компилятор видел a >
, за которым следует a >
.
С большей вероятностью сработает следующее:
template<>
std::ostreamamp; printFormatted<std::map<typename key, typename value> >(std::map<typename key, typename value> constamp; container, std::ostreamamp; os = std::cout) {
//...
}
Комментарии:
1. На самом деле это было исправлено в C 0x / C 11
2. Фантастика! Я этого не слышал, и это сводило меня с ума, когда я только начинал C . Я оставлю этот ответ, чтобы помочь любому, кто использует старый компилятор, но отредактируйте его, чтобы прояснить этот момент.