Разница между реализацией и специализацией в шаблонах c ++ - PullRequest
37 голосов
/ 12 октября 2010

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

template <typename T>
struct Struct
{

     T x;
};

template<>
struct Struct <int> //specialization
{

    //code
};

int main()
{
   Struct <int> s; //specialized version comes into play
   Struct <float> r; // Struct <float> is instantiated by the compiler as shown below

}

Создание Struct <float> компилятором

template <typename T=float>
struct Struct
{
    float x;
}

Верно ли мое понимание создания и специализации шаблонов?

Ответы [ 6 ]

42 голосов
/ 12 октября 2010

4 понятия:

(неявное) создание экземпляра : это то, что вы называете созданием экземпляра

явноеэкземпляр: : это когда вы указываете компилятору создать экземпляр шаблона с заданными типами, как это

template Struct<char>; //used to control the PLACE where the template is inst-ed

(явная) специализация: это то, что вы называете специализацией

частичная специализация это когда вы даете альтернативное определение шаблону для подмножества типов, например так:

template<class T> class Struct<T*> {...} //partial specialization for pointers
15 голосов
/ 12 октября 2010

В чем разница между специализацией и реализацией в контексте шаблонов C ++?

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

Если присутствует специализация , то для (набора) специальных параметров шаблона, определенных этой специализацией, вместо этой Компилятор создаст.

10 голосов
/ 12 октября 2010

Специализация шаблона фактически меняет поведение шаблона для определенного типа. например, преобразовать в строку:

template<typename T> std::string convertToString( const T& t )
{
   std::ostringstream oss;
   oss << t;
   return oss.str();
}

Давайте специализируемся на этом, хотя, когда наш тип уже является std :: string, так как бессмысленно проходить через ostringstream

template<> std::string convertToString( const std::string & t )
{
   return t;
}

Вы можете специализироваться и на занятиях.

Теперь инстанцирование: это сделано, чтобы позволить вам переместить компиляцию для определенных типов в одну единицу компиляции. Это может сэкономить вам время на компиляцию, а иногда и наворот. Допустим, мы превращаем вышеупомянутое в класс с именем StringConvert, а не в функцию.

template<typename T>
class StringConvert
{
 public:
  // 4 static functions to convert from T to string, string to T,
   // T to wstring and wstring to T using streams
 };

Мы преобразуем много целых чисел в строки, чтобы мы могли создать их экземпляр: поместите это в один заголовок

 extern template class StringConvert<int>;

Поместите это в одну единицу компиляции:

 template class StringConvert<int>;

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

7 голосов
/ 12 октября 2010

Обзор

  • Специализация: класс, функция или член класса, которые вы получаете, подставляя аргументы шаблона в параметры шаблона шаблона класса или функции.

  • Instantiation: Акт создания специализации из шаблона или члена шаблона класса. Специализация может быть создана из частичной специализации, члена шаблона класса или из основного класса или шаблона функции.

Явная специализация - это специализация, которая определяет класс, функцию или член явно , без создания экземпляра.

6 голосов
/ 12 января 2018

В c ++ 11.

создание экземпляра:

Создание шаблона с заданными аргументами шаблона

template <typename T>
struct test{ T m; };

template test<int>;//explicit instantiation

, что приводит копределение структуры с идентификатором test<int>

test<int> a;//implicit instantiation

, если template <typename T> struct test был создан с аргументом T = int перед (явным или неявным), то это просто экземпляр структуры.В противном случае он будет инстанцировать template <typename T> struct test с аргументом T = int сначала неявно, а затем инстанцировать экземпляр структуры test<int>

специализация:

специализация все еще шаблон , вам все еще нужно создать экземпляр, чтобы получить реальный код.

template <typename T>
struct test{ T m; };
template <> struct test<int>{ int newM; } //specialization

Наиболее полезная специализация шаблона - это, вероятно, то, что вы можете создавать различные шаблоны для различных аргументов шаблона, что означает вымогут иметь разные определения класса или функции для разных аргументов шаблона .

template<> struct test<char>{ int cm; }//specialization for char
test<char> a;
a.cm = 1;

template<> struct test<long> { int lm; }//specialization for long
test<long> a;
a.lm = 1;

В дополнение к этим полным специализациям шаблона с выше, есть (только шаблон класса) выходы частичная специализация шаблона также.

template<typename T>
struct test {};
template <typename T> struct test<const T>{};//partial specialization for const T


template <typename A, typename B>
struct test {};
template <typename B> struct test<int, B>{};//partial specialization for A = int
0 голосов
/ 05 октября 2017

Специализированный шаблон уже не просто шаблон.Вместо этого это либо фактический класс, либо фактическая функция.

Специализация происходит из экземпляра или явной специализации, см. 14.7.4 ниже.

Инстанцирование основано на первичномопределение шаблона.Образец неявной реализации шаблона класса,

template<typename T>
class foo {}

foo<int> foo_int_object;

Образец явной реализации шаблона класса,

template class foo<double>;

Явная специализация имеет определение, отличное от своего основного шаблона.

template<>
class foo<bool> {}

// извлечение из стандартных

14 шаблонов

14.7 Создание экземпляров и специализация шаблонов

4 Создание экземпляров специализации шаблонов может быть неявно создано (14.7.1) длязаданный список аргументов или явная реализация (14.7.2).Специализация - это класс, функция или член класса, который либо создан, либо явно специализирован (14.7.3).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...