специализация функций шаблона c — неправильное количество аргументов шаблона?

#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 . Я оставлю этот ответ, чтобы помочь любому, кто использует старый компилятор, но отредактируйте его, чтобы прояснить этот момент.