Как специализировать или перегружать глобальную шаблонную функцию для всех экземпляров шаблонного класса?

Как я могу специализировать или перегрузить функцию func так что специализация обрабатывает все экземпляры MyClass? Предполагать func это библиотекарь функция (как std::swap например) поэтому я не могу изменить funcи я не могу заменить или обернуть его, я должен специализировать его.

#include <iostream>

template<typename T>
class MyClass
{
};

template<typename T>
void func(const T&)
{
std::cout << "Default" << std::endl;
}

// I don't want to copy this stuff for every instance of MyClass
template<>
void func<MyClass<int>>(const MyClass<int>&)
{
std::cout << "Specialization" << std::endl;
}

int main(int, char**)
{
func(int(0)); // "Default"
func(MyClass<int>()); // "Specialization"
func(MyClass<double>()); // "Default" but I want "Specialization" here

return 0;
}

1

Решение

Вот несколько примеров того, что вы можете сделать.

template<typename T>
void func(const T&)
{
std::cout << "Default" << std::endl;
}

template<template<typename> class A , typename B>
void func(const A<B>&)
{
std::cout << "Overload All templated classes with one templated argument B" << std::endl;
}

template<typename T>
void func(const MyClass<T>&)
{
std::cout << "Overload Myclass with some templated argument T" << std::endl;
}
2

Другие решения

Если вы не можете изменить глобальный func в любом случае, и все же хотите избежать копирования, можно использовать макрос для автоматизации повторяющихся действий.

#define Specialize(TYPE) \
template<> \
void func<MyClass<TYPE>>(const MyClass<TYPE>&) \
{ \
std::cout << "Specialization" << std::endl; \
}

Specialize(int);
Specialize(double);

Если у вас есть свобода изменять MyClass<T>, а затем разместить все общие функции MyClass<T> в общий не шаблонный базовый класс:

template<typename T>
class MyClass<T> : public MyClassBase // <---- a common base class
...

И просто перегрузить или специализировать func() только для MyClassBase:

void func(const MyClassBase&)
{
std::cout << "Specialization" << std::endl;
}
0

По вопросам рекламы [email protected]