#c #class #templates
#c #класс #шаблоны
Вопрос:
Я знаю, что определения шаблонных классов похожи:
template <class TYPE>
class cars{
public:
TYPE myCar;
}
но где-то я сталкивался с этим фрагментом кода:
template <class T>
class polynomialT {
...
}
**************************************
class GFNUM2m {
...
}
**************************************
template class polynomialT<GFNUM2m>;
последняя строка для меня расплывчата? кто-нибудь знает, в чем дело? является ли это объектом класса polynomialT?(кажется, не потому, что у него нет имени) это шаблон?(кажется дубликатом, потому что он был шаблонизирован один раз)
Ответ №1:
template class polynomialT<GFNUM2m>;
Это запрос на явное создание экземпляра шаблонного класса polynomialT
с GFNUM2m
помощью, включая создание экземпляров всех его не шаблонных функций.
Вот некоторые случаи, когда это необходимо:
- Когда вы хотите избежать создания нескольких экземпляров шаблона (которые затем удаляются компоновщиком);
- Когда вы хотите убедиться, что полный шаблон может быть создан даже для тех (не шаблонных) функций, которые не вызываются;
- Когда вы хотите предоставить определения шаблонов в файле .cpp;
Комментарии:
1. @Seth Carnegie: Когда вы хотите избежать создания нескольких экземпляров шаблонов (которые затем удаляются компоновщиком); когда вы хотите убедиться, что полный шаблон может быть создан даже для тех функций, которые не вызывались; когда вы хотите предоставить определения шаблонов в .cpp файле; и, вероятно, в некоторых других случаях…
2. Это потенциально очень полезно, я удивлен, что никогда не сталкивался с этим раньше.
Ответ №2:
последняя строка эквивалентна:
class polynomialT {
protected:
GFNUM2m *coeff; // array of coefficients (? see below)
int degree;
...
}
GFNUM2m *coeff
это не массив, это просто указатель на GFNUM2m
переменную. Массив и указатель каким-то образом связаны, например, вы можете динамически выделять массив с помощью coeff = new GFNUM2m[10]
, но это не рекомендуется.
Комментарии:
1. да, но это больше похоже на прямое объявление типа, который используется через несколько строк после
2. Динамическое выделение массивов не рекомендуется, в некоторых ситуациях это абсолютно необходимо… Рекомендуется использовать только при необходимости.
Ответ №3:
На самом деле, это _explicit создание экземпляра шаблона. Используйте это, чтобы заставить компилятор генерировать все (не вложенные в шаблон) члены класса template. Иногда это удобно при внешней привязке к шаблонному коду, чтобы предотвратить дублирование объектного кода или отсутствие внешних элементов (когда методы становятся встроенными).
Специализации шаблонов кажутся похожими, но требуют template<>
объявления специализации уже объявленного шаблона. Кроме того, они определили бы альтернативное определение класса для этого конкретного параметра шаблона (как упоминает @rerun).
Теперь, в точке их пересечения, вы могли видеть
template<> class polynomialT<GFNUM2m>;
Который ЯВЛЯЕТСЯ, по сути, заранее объявленной специализацией шаблона. Это послужило бы для того, чтобы предотвратить автоматическое создание компилятором шаблона класса для этого параметра типа во время остальной части модуля перевода.
Комментарии:
1. Специализации шаблонов есть
<...>
послеtemplate
.2. @K-ballo: Эй, я думаю, я извлек кое-какую полезную дополнительную информацию из этой путаницы. Спасибо
Ответ №4:
Последняя строка представляет собой прямое объявление polynomialT
шаблона класса с шаблонным параметром GFNUM2m
, который также создает экземпляр шаблонного класса.
Ответ №5:
это означает, что шаблон в классе polynomialT теперь является классом GFNUM2m.
Комментарии:
1. прошу прощения? для меня это еще более расплывчато.
2. Я имею в виду, что это прямое объявление для элемента данных шаблона polynomialT. Итак, мы можем создать объект polynomialT, который имеет экземпляр GFNUM2m..
3. Прошу прощения, но это просто неточно. Вся идея прямого объявления заключается в том, чтобы назвать неполный тип. В этом случае он скорее создает полный тип (из шаблона clas). -1