Частичная специализация
Частичная специализация - это механизм языка C++, позволяющий задать особую версию шаблона класса для некоторого подмножества его параметров. В отличие от полной специализации, где все аргументы шаблона фиксированы, при частичной специализации часть параметров остаётся обобщённой. Компилятор выбирает частичную специализацию, когда аргументы шаблона соответствуют заданному образцу. Частичная специализация применима только к шаблонам классов и шаблонам переменных, но не к шаблонам функций.
Синтаксис
// Основной шаблон
template <typename T, typename U>
class MyClass
{
// ...
};
// Частичная специализация
template <typename T>
class MyClass<T, int>
{
// ...
};
Пример
Давайте рассмотрим базовый пример частичной специализации.
Создадим шаблон класса Printer, который выводит
информацию о типах. Для случая, когда второй параметр
является типом int, определим отдельную реализацию:
#include <iostream>
using namespace std;
template <typename T, typename U>
class Printer
{
public:
void print()
{
cout << "General template" << endl;
}
};
template <typename T>
class Printer<T, int>
{
public:
void print()
{
cout << "Partial specialization for int" << endl;
}
};
int main()
{
Printer<double, double> p1;
p1.print();
Printer<double, int> p2;
p2.print();
return 0;
}
Результат выполнения кода:
"General template"
"Partial specialization for int"
Пример
Частичную специализацию можно применять и для шаблонов с параметрами-указателями. Давайте специализируем шаблон для случая, когда оба типа являются указателями:
#include <iostream>
using namespace std;
template <typename T, typename U>
class Holder
{
public:
void info()
{
cout << "Non-pointer types" << endl;
}
};
template <typename T, typename U>
class Holder<T*, U*>
{
public:
void info()
{
cout << "Both types are pointers" << endl;
}
};
int main()
{
Holder<int, double> h1;
h1.info();
Holder<int*, double*> h2;
h2.info();
return 0;
}
Результат выполнения кода:
"Non-pointer types"
"Both types are pointers"
Пример
Рассмотрим частичную специализацию для шаблона переменной.
Начиная со стандарта C++14, шаблоны переменных также
поддерживают частичную специализацию. Создадим шаблон
переменной value и специализируем его для типа
int:
#include <iostream>
using namespace std;
template <typename T, typename U>
const char* value = "general";
template <typename T>
const char* value<T, int> = "specialized for int";
int main()
{
cout << value<double, double> << endl;
cout << value<double, int> << endl;
return 0;
}
Результат выполнения кода:
"general"
"specialized for int"
Смотрите также
-
ключевое слово
template,
которое объявляет шаблон -
ключевое слово
typename,
которое объявляет параметр типа -
механизм
полной специализации,
который фиксирует все аргументы шаблона -
концепция
шаблона класса,
для которого применима частичная специализация