明らかに、型をパラメータ化する 1 つの方法は、プリプロセッサを使用することです。
#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;
}
これは と の 2 つの関数を実装divide_double
しdivide_int
ます。DIVIDE_TYPE
より複雑な (現実的な) 例では、実装は、異なる定義を持つ型ごとに個別にコンパイル (またはインクルード) される個別のコンパイル ファイルにある可能性があります。
実際のジェネリックと比較した欠点は、さまざまな型の実装が自動的に生成さDIVIDE_CALL(mytype, x, y)
れないことです。つまり、実装mytype
が生成されません。(もちろん、これはいくつかの比較的単純なスクリプトで調整できますが、実際にはもう C を使用していないと主張する人もいるかもしれません。よりきれいなジェネリックが組み込まれた言語が存在します。=)
いずれにせよ、これはデータ構造など、実際のデータ型 (void *
ポインタではない) が必要な場合に機能します。