Кратко:

Частичная специализация позволяет создавать специализированные версии шаблонов для подмножества типов параметров. Это особенно полезно для шаблонных классов, когда необходимо предоставить особое поведение для конкретных типов или комбинаций типов.

Основные свойства:

  • Гибкость: возможность адаптировать шаблоны для частично фиксированных типов.
  • Улучшение производительности: создание оптимизированного кода для конкретных случаев.
  • Поддержка обобщенного программирования: сохранение общего шаблона для остальных типов.

Пример кода

Общий шаблон класса

#include <iostream>
 
template<typename T, typename U>
class MyClass {
public:
    void display() {
        std::cout << "Generic MyClass" << std::endl;
    }
};

Частичная специализация для одного типа

template<typename T>
class MyClass<T, int> {
public:
    void display() {
        std::cout << "MyClass partially specialized for int" << std::endl;
    }
};

Частичная специализация для указателей

template<typename T>
class MyClass<T*, T*> {
public:
    void display() {
        std::cout << "MyClass partially specialized for pointer types" << std::endl;
    }
};

Использование шаблона и его специализаций

int main() {
    MyClass<double, char> obj1;
    obj1.display(); // Вывод: Generic MyClass
 
    MyClass<float, int> obj2;
    obj2.display(); // Вывод: MyClass partially specialized for int
 
    MyClass<int*, int*> obj3;
    obj3.display(); // Вывод: MyClass partially specialized for pointer types
 
    return 0;
}

Объяснение примера

  • Общий шаблон: MyClass<T, U> определяет общий случай для двух произвольных типов.
  • Частичная специализация для int: MyClass<T, int> определяет поведение, когда второй тип - int.
  • Частичная специализация для указателей: MyClass<T*, T*> определяет поведение для указателей на один и тот же тип.

Частичная специализация шаблонных функций

Для функций в C++ нет частичной специализации, но можно использовать перегрузку для достижения схожего эффекта.

#include <iostream>
 
// Общий шаблон функции
template<typename T, typename U>
void func(T t, U u) {
    std::cout << "Generic function" << std::endl;
}
 
// Перегрузка функции для частичного случая
template<typename T>
void func(T t, int u) {
    std::cout << "Function specialized for int" << std::endl;
}
 
int main() {
    func(1.0, 'a'); // Вывод: Generic function
    func(1.0, 2);   // Вывод: Function specialized for int
 
    return 0;
}

Объяснение примера

  • Общий шаблон функции: func(T t, U u) обрабатывает любые два типа.
  • Перегруженная функция: func(T t, int u) обрабатывает случаи, когда второй аргумент - int.