それ (dynamic duck typing) C++ でできるよ +α

http://d.hatena.ne.jp/gnarl/20080801/1217523822
元のエントリが静的なものと動的なものを比較していますので,それに対する批判としてはまったく正当なものなのでそこには異論はありません.ですが,蛇足として, static duck typing が与えられればそこから dynamic duck typing を導出することは C++ ではできるんだよにゃ,ということは指摘しておきたいのです.これは,書籍のような整理された形でまとめられていない技法を用いますので,しばしばこういう議論の中で見落とされるのですが.

それ C++ でできるよ,というのはつまり,要件が「ダックタイピングだと共通の基底クラス/インタフェースがなくても統一的やりかたで『かつ動的に』メソッド呼べる」だけなら, C++ でも特に問題なく記述できる,ということです.ただし,それが簡潔なコードに収まるかはさておいて.実際,この技法は,自分の感覚では「簡潔なコード」には収まっていないように思います.

で,実際できるよ,という指摘だけにとどまりません.この技法は toy program の上だけのお遊びの技法ではまったくない. C++ コミュニティにおいては,この技法に関して十分な実績のある応用例がすでに存在します.また,将来的にもこの技法を積極的に活用する方向性が C++ コミュニティの主流な潮流であるように見受けられます.

十分な実績のある応用例.たとえば boost::shared_ptr (std::tr1::shared_ptr) の実装 (実際には shared_ptr で使用する動的削除子の実装) は「アヒルのように鳴くならアヒルだろう」もとい「デストラクタが発動できるなら C++ のオブジェクトだろう」に基づいたものといえます.もちろん,ここでは動的な duck typing の実例として引き合いに出しています.ただ, boost::shared_ptr が動的なものを採用している理由はやや技術的に複雑な背景があります.そこら辺については,たとえば http://d.hatena.ne.jp/Cryolite/20060108#p1 などを参考にしていただきたいです.

boost::shared_ptr を使っていたけれどそんなこと知らなかった,という方が居るのなら,まさにこの技法が (少なくともライブラリの実装技法としては) 大いに成功を収めていることを示しているのではないでしょうか.この技法は簡潔でないコードになると書きましたけれども,ライブラリの実装技法として採用した場合に限っていえば,その簡潔でないコードを書かなければならない苦労はライブラリコード内に閉じています.その苦労を一身に背負うのはライブラリ実装者であり,ライブラリのユーザではありません.

将来的にこの技法を積極的に活用する方向性が C++ コミュニティの主流な潮流であることの証左.たとえば C++0x のドラフトを読めば,新規に登場するライブラリコンポーネントがすべからく,ユーザ定義型に対して何らの侵入的な要求 (たとえば継承) を必要としないように統一されているのが分かります.

もちろん,侵入的な要求をユーザ定義型に求めない,というライブラリのあり方の恩恵を受けない方も居るかも知れません.それは以下のような方でしょう.

  • ライブラリで使用するユーザ定義型はすべて自分で書いたもので,クラスに侵入的な変更 (継承関係など) を導入することに何の障壁も無いよ
  • 第3者・サードパーティが書いたユーザ定義型をライブラリで使用するけれど,それらの型すべてに対して定義を自由に書き換える権利を有していて,なおかつその定義がすべて可視な状態にあるのよ
  • とても速いコンパイラを持っているので,そのクラスの定義を書き換えることによってそのクラスの定義に依存しているすべてのビルドチェインの再コンパイルが起きたとしても何の造作も無いことよ

以上のとおり, C++ では dynamic な duck typing が可能であり,その技法は十分な応用実績をもち,将来的にも有用といえるかと思います.

最後に本当の蛇足. static duck typing がある文脈で有益であるのと同時に dynamic duck typing もある文脈では有益であるのは上に指摘したとおりです.自分としては,この両者ともに文脈に合わせて自由に選択できるのが理想かと思います.

C++ において static duck typing を実現するのは, C++ において dynamic duck typing を実現することよりも簡潔であることは確かです.一方,今の (そして C++0x の) 言語機能では,ある static duck typing が given であるときに,対応する dynamic duck typing を導出するためには,面倒なコードを書かなければいけません.そこで自分としては,ある static duck typing を実現しているときに,それに対応する dynamic duck typing を半自動で実現するような言語機能がほしい,という帰結に至ります.そのような変換を簡潔に行うための言語機能を最も primitive な形で取り出すと,恐らく C++ ではそれは AOP になると自分は予想するのですが,まー,それは予想するだけー.