C で汎用コンテナーが必要な場合、一般的なアプローチの 1 つは を使用することvoid*
です。ジェネリック コンテナーが独自の解放関数を持つカスタム構造体を保持している場合、その関数を要求する可能性があります。
struct Foo {...};
Foo *Foo_Allocate(...);
void Foo_Deallocate(const Foo*);
int main(void)
{
/* Let's assume that when you create the list you have to
specify the deallocator of the type you want to hold */
List *list = List_Allocate(Foo_Deallocate);
/* Here we allocate a new Foo and push it into the list.
The list now has possession of the pointer. */
List_PushBack(list, Foo_Allocate());
/* When we deallocate the list, it will also deallocate all the
items we inserted, using the deallocator specified at the beginning */
List_Deallocate(list);
}
しかし、ほとんどの場合、deallocator 関数の型は、void*
typedef void (*List_FnItemDeallocator)(const void*);
問題は、ではなくFoo_Deallocate
がかかることです。署名が一致しない場合でも、関数を渡すことは安全ですか? C ではポインター型は必ずしも同じサイズではないため、おそらくそうではありません。const Foo*
const void*
それが不可能な場合は、すべてのデアロケーター関数に、const void*
関連する型へのポインターではなく を取得させて、汎用コンテナーと互換性を持たせることをお勧めしますか?