W.I.S. Laboratory
menu-bar

C


_Genericを使ってC言語でダックタイピングっぽいことをしてみる

C99で追加された機能「_Generic」と関数型マクロを組み合わせて使うと、関数のオーバーロードっぽいことができる。
オーバーロードができるということは、型の制限はあるものの関数テンプレートのようなことができるということだ。
ということは親構造体を持たなくてもダックタイピング(静的ポリモーフィズム)っぽいことができるのか!?すごい。
ということでやってみた。

Cはその関数が同じか違うかを関数名だけで判別するので、C++のようにシグネチャが異なる同名関数を複数書くことができない。
なので別名の関数をそれぞれ書いておき、呼び出し元には関数型マクロを書く。
関数型マクロ内で_Genericを使い、引数の型に応じて目的の関数名に展開させる。
このようにコードを書き、1つの関数(実際は関数型マクロ)へ異なる型を放り込んでみる。
下のコードでいうと、「cry()」関数に、Dog型ポインタ、Cat型ポインタ、Mouse型ポインタをそれぞれ引数として与えているが、すべての型にあるメンバ関数「voice()」にちゃんとアクセスしている・・ように見える。

C++の関数テンプレートも、コード上では1つの関数に見えるが、引数としてやってくるすべての型の分だけ関数を量産してコンパイルしている。
C++は量産後の関数がコード上に見えていないが、Cの場合はそれがコード上に全部見えている(というか自分で書く)という違いだけだ。
つまり見えているか見えていないかの違いがあるだけで、やっていることはダックタイピングと言える・・と思う。
少なくともマクロでただその場に展開しただけのコードとは違い、型に応じた関数を呼び分けているところが静的ポリモーフィズムっぽい。


[ 戻る ]
saluteweb