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

#define my_type double

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

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

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

#if my_type == complex<double>

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

2
ulf 6 Ноя 2014 в 15:39

4 ответа

Лучший ответ

#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
8
M.M 6 Ноя 2014 в 12:45

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

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

1
Sebastian Redl 6 Ноя 2014 в 12:45

А как насчет полноценного шаблона вроде:

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

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

0
Dr. Debasish Jana 6 Ноя 2014 в 13:04

Идеи, похожие на @ 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. Попробовав это, я задаюсь вопросом, зачем мне писать такой код. Красиво и красиво - это что-то другое.

0
tgmath 6 Ноя 2014 в 13:16