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

Если у меня есть шаблон класса MyClass<T> и если я явно для int а также floatcpp файл) тогда я могу использовать 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> для всех поддерживаемых типов.

Учитывая, что я уже явно создал экземпляр класса для этих типов, он кажется не только избыточным, но и для больших проектов (например, над тем, над которым я работаю), и еще несколько строк, которые мне нужно поддерживать при каждом добавлении нового типа.

3 ответа

Решение

Это честно звучит как работа для макроса:

// 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>
{};
Другие вопросы по тегам