Вы можете использовать boost::enable_if
вместе с набором типов.
Определите список типов, который содержит все типы , которые вы хотите поддерживать, и напишите некоторую мета-функцию (и), чтобы проверить, существует ли данный список типа в списке, или нет, и затем передайте значение, которое метафункция возвращает enable_if
, чтобы включить / отключить класс.
Хорошо, я написал код для демонстрации. Тем не менее, он не использует boost::enable_if
(для экспериментов).
Вот рамки в первую очередь:
////////////////////////////////////////////////////////////
//framework
struct null_type {};
template<typename H, typename T=null_type>
struct typelist
{
typedef H Head;
typedef T Tail;
};
template<typename T, typename TList> struct exists;
template<typename T, typename Tail>
struct exists<T, typelist<T, Tail> >
{
static const bool value = true;
};
template<typename T, typename Head, typename Tail>
struct exists<T, typelist<Head, Tail> >
{
static const bool value = false || exists<T, Tail>::value;
};
template<typename T>
struct exists<T, null_type >
{
static const bool value = false;
};
template<bool>
struct compile_time_error;
template<>
struct compile_time_error<true> {};
-
Теперь следует код тестирования:
//////////////////////////////////////////////////////////////
//usage
typedef typelist<int> t1;
typedef typelist<short, t1> t2;
typedef typelist<char, t2> t3;
typedef typelist<unsigned char, t3> t4;
typedef t4 supported_types;//supported_types: int, short, char, unsigned char
template<typename T>
struct X
{
compile_time_error<exists<T,supported_types>::value> unsupported_type_used;
};
int main() {
//testing if exists<> work or not!
cout <<(exists<int,supported_types>::value)<< endl; //should print 1
cout <<(exists<unsigned int,supported_types>::value)<<endl;//should print 0
cout <<(exists<char,supported_types>::value)<< endl; //should print 1
cout <<(exists<long,supported_types>::value)<< endl; //should print 0
X<int> x1; //okay - int is supported!
//X<long> x2; //error - long is unsupported!
return 0;
}
, который прекрасно компилируется ( ideone ) и выдает следующее (для операторов cout
):
1
0
1
0
Но если вы раскомментируете строку X<long> x2;
в приведенном выше коде, она не будет компилироваться, поскольку long
является неподдерживаемым типом. И это дает эту ошибку, которую легко читать и понимать ( ideone ):
prog.cpp: в экземпляре X:
prog.cpp: 68: создан здесь
prog.cpp: 56: ошибка: «X :: unsupported_type_used» имеет неполный тип
prog.cpp: 38: ошибка: объявление "struct compile_time_error"
Надеюсь, это поможет вам.
Теперь вы можете написать шаблон класса с именем enable_if_supported
, который принимает два аргумента типа: T
и supported_types
. Вы можете получить свой класс от enable_if_supported
как:
template<typename T>
struct X : enable_if_supported<T, supported_types>
{
//your code
};
Это выглядит немного чисто. enable_if_supported
шаблон класса теперь определен в разделе фреймворка. Смотрите здесь, работая: http://www.ideone.com/EuOgc