2005年10月 2日
C++ のテンプレートでダックタイピング
Ruby や Python などの動的な言語では、ダックタイピング (duck typing) というテクニックが多用されています。
ダックタイピングは、同じインタフェースさえ備えていれば型は何でも構わない、という考え方に基づく多態 (polymorphism) の手法です。アヒルのように見えて、アヒルのように鳴くなら、アヒルに違いない、というわけです。
そして、現在最も注目を浴びている言語である C++ でもテンプレートを用いるとダックタイピングを行えます。
ダックタイピングを使うと、継承関係を無視して多態的にオブジェクトのメソッドを呼び出せます。たとえば、次の Ruby のコードでは、func に Duck と Foo のどちらのオブジェクトを渡しても正常に動作します。これは Duck, Foo ともに、共通のインタフェースを持つ quack メソッドを備えているためです。quack を持たないオブジェクトを渡すと実行時エラーになります。
class Duck def quack; puts "gaaa"; end end class Foo def quack; puts "...."; end end def func(ducky) ducky.quack end duck = Duck.new foo = Foo.new func(duck) func(foo)
C++ では同様のコードを次のように書けます。func は template を使って「アヒルのようなオブジェクト」のリファレンスを受け取っています。quack() を持たないオブジェクトを渡すと実行時エラーではなくコンパイルエラーになるのがポイントです。
#include <iostream> using namespace std; struct Duck { void quack() const { cout << "gaaa" << endl; } }; struct Foo { void quack() const { cout << "...." << endl; } }; template <typename Ducky> void func(const Ducky& ducky) { ducky.quack(); } int main () { Duck duck; Foo foo; func(duck); func(foo); return 0; }
C++ のテンプレートは相当おもしろいので Modern C++ Design を読んで勉強中です。
参考ページ
- きまぐれ日記: C++ で多態
- Duck typing - Wikipedia, the free encyclopedia
- Duck Typing (c2.com)
- Ruby: Duck Typing (RubyGarden)