Я хочу сделать " stati c диспетчеризация " во время компиляции через типы.
В частности, есть семейство функций (параметризованных по типу), и я хочу чтобы выбрать функцию из этого семейства (во время компиляции) на основе типа аргумента.
В C11
это можно сделать с помощью _Generic()
.
Например, следующий код работает.
// gcc generic.c -o generic && ./generic
#include <stdio.h>
void foo_int() { printf("%s\n", __func__); } // Arbitrary code to show that this works
void foo_float() { printf("%s\n", __func__); } // Arbitrary code to show that this works
void foo_double(){ printf("%s\n", __func__); } // Arbitrary code to show that this works
#define foo_api0(VAL) \
_Generic(VAL, \
int: foo_int, \
float: foo_float, \
double: foo_double \
)()
int main(){
foo_api0(2);
foo_api0(4.f);
foo_api0(8.);
}
Однако теперь предположим, что в макросе foo_api
я не хочу передавать значение нужного типа , но я хочу передать желаемый тип самого . (Причины , почему не важны для текущего обсуждения. Предположим, что такие причины существуют.)
Например, вместо
foo_api0(2);
foo_api0(4.f);
foo_api0(8.);
Я хочу сделать
foo_api1(int);
foo_api1(float);
foo_api1(double);
Этого можно добиться, используя сам тип для создания вспомогательной переменной (ie. «Свидетель» типа):
#define foo_api1(TYPE) ({ \
TYPE witness; \
_Generic(witness, \
int: foo_int, \
float: foo_float, \
double: foo_double \
)(); \
})
, и тогда оба API работают:
int main(){
foo_api0(2);
foo_api0(4.f);
foo_api0(8.);
foo_api1(int);
foo_api1(float);
foo_api1(double);
}
Мой вопрос:
Есть ли способ сделать это без использования такой вспомогательной переменной ? (Возможно, есть макрос / ключевое слово в C, который может делать вещи, основываясь на самом типе, а не на переменной этого типа?)
Например, было бы неплохо иметь что-то вроде:
#define foo_api1(TYPE) ({ \
_Generic(TYPE, \
int: foo_int, \
float: foo_float, \
double: foo_double \
)(); \
})