2014-11-06 3 views
2

Я хотел бы условно включить функции (или, в частности, конструкторы) в зависимости от типа переменной I, определенного на уровне препроцессора, например.Препроцессор C++

#define my_type double 

и в любой момент я могу условно включать функцию

#if my_type == double 
void my_fct(); 
#endif 

, который работает отлично. Однако, как это сделать, если я хочу назначить шаблонный тип для my_type. Используя сложный двойной, например, я бы наивно просп мысль

#if my_type == complex<double> 

будет работать, но препроцессор кажется интерпретировать последний «>» в ​​качестве оператора на уровне препроцессора. Я не вижу способа использования typedefs, так как я хочу, чтобы препроцессор выполнял условное включение. Конечно, я мог бы создать шаблон для всего класса и не использовать препроцессор для этой задачи, но сейчас я бы предпочел не делать этого. Кроме того, всегда можно определить еще один флаг препроцессора в дополнение к типу, но это кажется довольно грязным.

+0

Знаете, вы можете сделать функцию шаблоном, а не всем классом, если хотите. – icabod

+0

Я полностью не согласен с тем, что ваше последнее решение «кажется довольно грязным».Используйте typedefs для псевдонимов типов и препроцессор для условного кода. – molbdnilo

ответ

8

#if my_type == double не проверяет, были ли вы сделаны #define my_type double. На самом деле это всегда будет правдой.

В препроцессора арифметике можно использовать только целое число константных выражений, поэтому вам придется создать что-то вроде:

// from your makefile or whatever 
#define MY_TYPE MY_DOUBLE 

...

// in header file 
#define MY_INT 3 
#define MY_DOUBLE 4 
#define MY_COMPLEX_DOUBLE 5 

#if MY_TYPE == MY_DOUBLE 
    typedef double my_type; 
#elif MY_TYPE == MY_INT 
    typedef int my_type; 
#elif MY_TYPE == MY_COMPLEX_DOUBLE 
    typedef complex<double> my_type; 
#endif 
1

Я очень удивлен, что my_type == double работы ; это определенно не должно. Препроцессор может оценивать только простые числовые выражения.

Таким образом, ответ отрицательный, вы не можете работать с типами шаблонов (препроцессор не знает о типах, он просто заменяет токены). Если вам нужна логика на уровне типа, вам нужны шаблоны.

+2

Это «работает», потому что буквенно-цифровые маркеры заменяются на '0' для арифметики, поэтому это проверяет, если' 0 == 0' –

+0

@MattMcNabb Не знал этого, интересно. Думаю, это так, что '#if MY_FEATURE_DEFINE == 1' работает? –

+0

Вероятно, есть много кода, который использует это (например, '#if __cplusplus> 20110101') –

0

насчет полноценный шаблон, как:

template <class T> 
void my_fct() { 
// your code based on T as a type 
} 

И вы называете как: my_fct<int>, my_fct<double> и т.д., чтобы перейти в тип данных для соответствующего шаблона экземпляра.

+0

Спасибо за предложение. Это действительно хорошо работает для нормальной работы, но не в моем случае. Я сформулировал свой пример в заблуждении: я условно хочу включить разные конструкторы класса в зависимости от типа данных, так как некоторые операции литья не работают автоматически. Но он должен работать с предложенным выше методом. Еще раз спасибо! – ulf

0

Подобные идеи как @ Debasish-Jana: использование в качестве typtdef и шаблонных функций, это немного уродливые ищет:

type typedef double my_type; 

и функцию для double случая:

template<typename T = my_type> 
typename std::enable_if<std::is_same<T,double>::value, void>::type 
cnt() 
{ 

} 

И еще или номера cmplex:

template<typename T = my_type> 
typename std::enable_if<std::is_same<T,std::complex<double>>::value, void>::type 
cnt() 
{ 

} 

Пример: https://ideone.com/aXupSa. Пробовав это, я задаюсь вопросом, почему я написал код вроде этого. Приятно и красиво - это что-то еще.

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