スタックを扱うライブラリの実装

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
lisp implementer

スタックを扱うライブラリの実装

#1

投稿記事 by lisp implementer » 9年前

お世話になります。

Cでいわゆるスタックを実装し、pushやpopなどの関数を作ったのですが、これを様々な型のデータを放り込める汎用的なライブラリにしたいと思っています。

ただ、個々の関数の引数には型を設定しなければならず、例えばint型のデータを次々に放り込めるスタックとして定義してしまえば、他の型のデータを放り込みたい時にすべての関数の引数の型の部分を書き換えなければなりません。

そこでスタックを実装したファイルでは型をobjectと表記し、それを別のファイルからincludeする時にtypedefでobjectの示す実際の型を逐次定義するようにしました。これは1種類のスタックを使う時には上手く行くのですが、同じファイルでint型のスタックとint*型のスタックの二種類が必要となるとき、(typedef int object)と(typedef *int object)が競合してしまいます。

こうした場合、普通Cではどのようにライブラリを作るのでしょうか? ご意見お聞かせ頂ければ嬉しく思います。

YuO
記事: 947
登録日時: 14年前
住所: 東京都世田谷区

Re: スタックを扱うライブラリの実装

#2

投稿記事 by YuO » 9年前

とりあえず,互換性に問題が無いならばC++を使う,が解になり得ます。
というか,C++のtemplateは元々このようなものに対処するために作られた物です。

Cでの対処としては,#defineで型名を名前の一部にするように作ることでしょうか。

コード:

#define MYSTACK_TYPE(type) struct mystack_##type

#define MYSTACK_IMPL(type) void mystack_initialize_##type (struct mystack_##type * ptr) \
{ \
    /* 初期化処理 */ \
} \
void mystack_push_##type (struct mystack_##type * ptr, type value) \
{ \
    /* push処理 */ \
} \
type mystack_pop_##type (struct mystack_##type * ptr) \
{ \
    /* pop処理 */ \
}

#define MYSTACK_DEF(type) void mystack_initialize_##type (struct mystack_##type * ptr); \
void mystack_push_##type (struct mystack_##type * ptr, type value); \
type mystack_pop_##type (struct mystack_##type * ptr);

#define MYSTACK_INITIAILIZE(type, ptr) mystack_initialize_##type(ptr)
#define MYSTACK_PUSH(type, ptr, value) mystack_push_##type(ptr, value)
#define MYSTACK_POP(type, ptr) mystack_pop_##type(ptr)
int *などは使えず,typedefして使うことになります。
その上で,どこかのソースで使う型の分MYSTACK_IMPLを記述し,その他の利用する場所ではMYSTACK_DEFを記述します。

コード:

// どこか一箇所
typedef int * pint;
MYSTACK_IMPL(int)
MYSTACK_IMPL(pint)

コード:

// 使う側
typedef int * pint;
MYSTACK_DEF(int)
MYSTACK_DEF(pint)

int main (void)
{
    MYSTACK_TYPE(int) int_stack;
    MYSTACK_TYPE(pint) pint_stack;

    MYSTACK_INITIALIZE(int, &int_stack);
    MYSTACK_PUSH(int, &int_stack, 10);
// 以下略
こんな感じで使います。
template以前のC++でも,こんな感じでgenericなライブラリを作っていたようです。

lisp implementer

Re: スタックを扱うライブラリの実装

#3

投稿記事 by lisp implementer » 9年前

ご丁寧にありがとうございます。やはり#defineで強引に定義するしかないのですね。

Cでも比較演算子などは実質的に総称関数なので、もう少しスマートな方法が実装されていても良かったと思うのですが。C++という選択肢も検討してみます。ありがとうございます。

lisp implementer

Re: スタックを扱うライブラリの実装

#4

投稿記事 by lisp implementer » 9年前

解決を付け忘れたのでもう一度投稿します。ありがとうございました。

閉鎖

“C言語何でも質問掲示板” へ戻る