2013-12-15 1 views
4

C++ я нужен шаблон, который можно назвать так:Обнаружить, если тип существует в

int x = type_exists< std::vector<int> >::value; 

Это должно установить й до 1, если #include <vector> присутствовали (явно или транзитивно) ранее в источнике , в противном случае он должен установить x в 0.

Возможно ли это сделать на C++? Я использую GCC, поэтому расширения GCC также прекрасны.

Также можно немного изменить синтаксис вызова.

Нельзя запускать компилятор C++ дважды: сначала просто выяснить, получим ли мы ошибку компиляции.

+6

Что вы будете делать с такой функцией? – Mat

+3

Связано: [Как обнаружить существование класса с использованием SFINAE?] (Http://stackoverflow.com/questions/10711952/how-to-detect-existence-of-a-class-using-sfinae) –

+0

@gx_: Я не мог найти там ничего полезного. 'class_defined' потребовалось бы добавить' CLASS_DEFINED_CHECK' в заголовок 'vector', а' has_destructor' - ошибка компиляции для неопределенных классов. – pts

ответ

3

Это не возможно, я боюсь. Если бы мы должны были использовать не Defined идентификатор мы получим ошибку компиляции, что приводит к этому коду:

int x = type_exists< std::vector<int> >::value; 

не даже компиляции.

Кроме того, стандарт не указывает какую-либо директиву препроцессора, которая должна быть объявлена ​​в файле заголовка (вместо этого определена реализация) для стандартной библиотеки, поэтому вы не сможете обнаружить ее даже с помощью макросов препроцессора.

1

Это не то, что вы ищете, но это так близко, как вы можете добраться до type_exists черты:

template<class T> struct Void { typedef void type; }; 

template<class T, class U = void> 
struct type_exists { enum { value = 0 }; }; 

template<class T> 
struct type_exists<T, typename Void<T>::type> { enum { value = 1 }; }; 

По-видимому, это работает:

static_assert(type_exists<int>::value, "int is not defined"); 
static_assert(type_exists<SomeNonexistingType>::value, "expected compile-time error"); 

Это делает именно то, что он должен делать. Протестировано с помощью GCC 5.4.0.

+0

Действительно, с этим определением' type_exists', 'int x = type_exists > :: значение; 'не компилируется, если' 'не включен, поэтому это не решает мою проблему. – pts