Ну, очевидно, один из способов параметризуем типов является использование препроцессора, например:
#define DIVIDE_FUNC(type) divide_##type
#define DIVIDE_CALL(type, a, b) DIVIDE_FUNC(type)((a), (b))
#define DIVIDE_DECL(type) type DIVIDE_FUNC(type)(type a, type b)
#define DIVIDE_IMPLEMENTATION DIVIDE_DECL(DIVIDE_TYPE) { return a/b; }
#define DIVIDE_TYPE int
DIVIDE_IMPLEMENTATION
#undef DIVIDE_TYPE
#define DIVIDE_TYPE double
DIVIDE_IMPLEMENTATION
#include <stdio.h>
int main (void) {
int i = 5, j = 2;
(void) printf("int %d/%d = %d\n", i, j, DIVIDE_CALL(int, i, j));
(void) printf("double %d/%d = %f\n", i, j, DIVIDE_CALL(double, i, j));
return 0;
}
Это реализует две функции: divide_double
и divide_int
. В более сложном (реалистичном) примере реализация может быть в отдельном файле компиляции, который скомпилирован (или включен) отдельно для каждого типа с другим DIVIDE_TYPE
.
Недостатком по сравнению с реальными генериками является то, что реализации для разных типов не генерируются автоматически, то есть DIVIDE_CALL(mytype, x, y)
не приводит к созданию реализации для mytype
. (Конечно, это может быть организовано с некоторыми относительно простыми сценариями, но тогда можно утверждать, что вы больше не используете C, и есть языки с более красивыми встроенными генериками. =)
В любом случае это может работать для структур данных и таких, где желателен фактический тип данных (не указатель void *
).
Вы имеете в виду "generics"? http://download.oracle.com/javase/tutorial/extra/generics/index.html –
Вы переходите на C++ и используете шаблоны, вот как. – Puppy
@deadMG: Я знаю, как программировать то же самое, используя generics в C++. Я хотел знать, как это сделать на C. – Flash