2014-10-26 6 views
0

Если у меня есть класс шаблона 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> для всех поддерживаемых типов.

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

+0

Какой компилятор? – Surt

+0

Наш код - это кросс-платформа, поэтому 'MSVC++ 2010-2013',' CLang в XCode 6' и 'GCC'. – Samaursa

ответ

1

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

// 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" 
+0

Это неплохая идея. У меня будут дополнительные файлы, но ремонтопригодность компенсирует это. Потрясающие. – Samaursa

0

насчет:

template <typename T> 
struct Base {}; 

template <typename T> 
struct Supported; 

template <> 
struct Supported<int> : public Base<int> 
{}; 
+0

Это решает одну проблему, но открывает еще несколько. Теперь у меня есть заголовок, полный этих классов (это нормально), и мне придется переопределять все конструкторы. Самая большая проблема заключается в том, что мне придется менять заголовок каждый раз, когда новый тип поддерживается внутри (и явно инстанцируется). И для каждого нового типа мне придется это сделать, а это опять-таки больше обслуживания. Я бы предпочел набрать 'extern template class' в этом случае :) – Samaursa

+0

Вам нужно изменить заголовок, чтобы получить всю информацию о времени компиляции. В противном случае тип - это тип времени выполнения (boost :: any), которого вы избегаете, вероятно. –

1

Вы можете использовать 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

+0

Вы имеете в виду только 'value_type ' right? – Barry

+0

@Barry Почему только 'value_type '? – P0W

+0

Итак, в два раза. Я думаю, что либо сбрасываем 'typename' перед' enable_if' (который как вам не нужен), либо добавляем ':: type' в конце, чтобы вы могли его сбросить в' MyClass2'. Лично мне нравится использовать псевдонимы шаблонов, чтобы избежать того, что во всем мире есть «typename X :: type». – Barry

 Смежные вопросы

  • Нет связанных вопросов^_^