Если у меня есть шаблон класса MyClass<T>
и если я явно для int
а также float
(в cpp
файл) тогда я могу использовать extern template class MyClass<int>
а также extern template class MyClass<float>
чтобы любой экземпляр модуля компиляции, встречающий этот класс, не создавал его для int
а также float
без необходимости. Конечно, для любого другого типа класс все равно будет создан.
Теперь у меня есть класс MyClass2<T>
который работает только с int
, float
, char
, double
, short
и их неподписанные варианты, где это применимо. Поскольку я знаю все типы заранее, определения всех методов в этом классе находятся в cpp
файл. Это также, где я явно создаю экземпляр MyClass2<T>
для всех вышеперечисленных типов. В шапке у меня есть static_assert
предотвращение создания пользователем MyClass2<T>
с неподдерживаемым типом.
Есть ли способ полностью предотвратить MyClass2<T>
от создания экземпляров (например, extern template class MyClass2;
хотя я знаю, что это не работает) для всех типов включая поддерживаемые типы? Как поймать все за extern template
? Я хочу не печатать extern template class MyClass2<int>
для всех поддерживаемых типов.
Учитывая, что я уже явно создал экземпляр класса для этих типов, он кажется не только избыточным, но и для больших проектов (таких как тот, над которым я работаю), и еще несколько строк, которые мне нужно поддерживать каждый раз, когда добавляется новый тип.
Это честно звучит как работа для макроса:
// explicit_instantiations.h
#ifndef PERFORM_INSTANTIANTION
#define EXTERNALLY_INSTANTIATED extern
#else
#define EXTERNALLY_INSTANTIATED
#endif
EXTERNALLY_INSTANTIATED template class MyClass<int>;
EXTERNALLY_INSTANTIATED template class MyClass<float>;
// etc.
// header
#include "explicit_instantiations.h"
// cpp file
#define PERFORM_INSTANTIATION
#include "explicit_instantiations.h"
Вы можете использовать SFINAE что-то вроде следующего
template<typename T>
using value_type = typename std::enable_if<
std::is_same<float, T>::value ||
std::is_same<double, T>::value
//...other supported types goes here
>::type ;template<class T, class Enable = void>
class MyClass2 ;
template<class T>
class MyClass2<T, value_type<T> >
{
};
MyClass2<float> t;
MyClass2<int> t1; // Error !
Увидеть Here
Как насчет:
template <typename T>
struct Base {};
template <typename T>
struct Supported;
template <>
struct Supported<int> : public Base<int>
{};