c++
ジェネリックのような機能を実装したい。整数とは別に、パラメーターは char 型やその他の型もサポートする必要があります。
void function t(int a[],int len);
これをC言語で実装するには?
C++ のように C にはテンプレートがないため、いくつかの異なるオプションがあり、目の前のタスクに応じて適切な場合があります。
プリプロセッサを使用して、いくつかの操作を単純にラップする基本MIN
/タイプ マクロなどの基本マクロを作成します。MAX
<
>
特定のデータ型 ( 、 など) に対して異なるバージョンの関数を記述しfunction_int(int...)
ますfunction_char(char...)
。
実装の詳細を知らずにデータを として取り込むジェネリック関数と、void*
データに作用し、このデータの操作方法を知っている関数によって呼び出される関数ポインターを作成します。
この場合、 のような関数を見てくださいbsearch
。検索キーと配列の型void *
は で、特定の型のデータに対して比較関数が渡されます。
void *bsearch(const void *key, const void *base, size_t nmemb, size_t size,
int (*compar)(const void *, const void *));
比較関数は、データの型を知る必要がある唯一のコード部分であるため、関数の汎用部分を 1 回記述するだけで済みます。ただし、上記のポイントと同様に、操作するデータ型ごとに関数を記述する必要があります。
これは、本C Unleashedで説明されていると思われる手法です。この本には、おそらく私が記憶から再現できるものよりも、もう少し洗練されたものが含まれています。
次のようなインクルード ファイルを使用できます。
/* function.tmpl */
#ifndef FUNCTION
#define FUNCTION_PASTE(X,Y) X ## _ ## Y
#define FUNCTION(X) FUNCTION_PASTE(function, X)
#endif
void FUNCTION(TYPE) (TYPE a[], int len) {
/* do something */
}
次に、次のように含めることができます。
#define TYPE int
#include "function.tmpl"
#undef TYPE
#define TYPE double
#include "function.tmpl"
#undef TYPE
そして、次のような関数を呼び出します。
int a[4];
FUNCTION(int)(a, 4);
double b[5];
FUNCTION(double)(b, 5);
次のようなことを試すことができます:
enum data_type { CHAR_TYPE, INT_TYPE };
void function t(void* buf, size_t len, enum data_type type) {
int* int_ary;
char* char_ary;
if (type == CHAR_TYPE) {
char_ary* = buf;
...
} else if (type == INT_TYPE) {
int_ary* = buf;
...
}
}
ハック的でエラーが発生しやすいですが、機能する可能性があります。型ごとに個別のバージョンではなく、1 つの統合された関数であるという点で、C++ とまったく同じではありません。
C でこれを行う慣用的な方法は、void* を渡すことです。しかし、実際に何かを行うには、追加の情報が必要です。