«ошибка слишком малого числа аргументов шаблона» при использовании класса шаблона с параметром шаблона по умолчанию в c ++ - PullRequest
0 голосов
/ 19 февраля 2020

У меня был класс, который работал нормально. Я хотел изменить его на класс шаблона. Предположим, у меня теперь есть:

template <MyTypes::smallType T = Mytypes::myInt>
class A{....}

Теперь предположим, что класс A используется во многих других файлах hpp и cpp, иногда путем включения файла заголовка, а иногда путем прямого объявления в виде:

template <MyTypes::smallType T> class A;

И он в основном используется как std::shared_ptr<A<>> в других классах и вызовах функций.

Теперь предположим, что у меня есть другой класс B, который очень похож на A, но используется в меньшем количестве мест (все еще в других cpp файлов через предварительное объявление), а не в shared_ptr.

template <MyTypes::smallType T = Mytypes::myInt>
class B{....}

При попытке компиляции я получаю сообщение об ошибке "слишком мало аргументов шаблона" для A<>, но не для B<> , Проект очень большой, и у меня нет догадок, чтобы привести простой пример с той же проблемой. Не могли бы вы помочь мне (даже по уловкам), что может быть причиной проблемы? Это может быть shared_ptr? Это могут быть typedef в виде typedef std::shared_ptr<A<>> APtr? Я также получаю сообщение об ошибке «шаблон неспециализированного класса или generi c нельзя использовать как шаблон или аргумент generi c для шаблона или generi c параметр 'param', ожидаемый реальный тип», если это может помочь с догадки.

Буду признателен за вашу помощь.

1 Ответ

1 голос
/ 19 февраля 2020

Проще говоря, предварительное объявление нуждается в параметрах по умолчанию. Просто посмотрите на это так, в упрощенной форме:

template<class T> A;
std::shared_ptr<A<>> a;

Когда компилятор видит это, это вся информация, которую он имеет. Таким образом, в этом случае A<> явно отсутствует тип для параметров шаблона. Теперь, если вы сделаете:

template<class T = int> A;
std::shared_ptr<A<>> a;

, тогда компилятор может сделать вывод, что A<> действительно A<int>.

Вот проблема с этим, хотя. С [temp.param]/12

Параметру шаблона не должны предоставляться аргументы по умолчанию двумя различными объявлениями в одной и той же области видимости.

[ Example:
template<class T = int> class X;
template<class T = int> class X { /* ... */ }; // error
—end example ]

Итак, если вы используете параметр по умолчанию в вашей предварительной декларации, вы не можете использовать его в самом шаблоне. Веселые времена.

Обман, чтобы обойти это, состоит в том, чтобы иметь дополнительный заголовочный файл, который содержит только предварительное объявление шаблона с параметрами по умолчанию, и все файлы, использующие шаблон, включают это вместо полного определения шаблона ( пока не требуется полное определение), включая определение шаблона. Определение шаблона не требует параметров по умолчанию. Не очень весело, но это сработает.

В качестве альтернативы, не пересылать объявление.

См. Примеры здесь

...