C++ template and C# Generics

comment でいいこと教えてもらったので修正。 id:matarillo さんありがとう。

C# いじってて Generics てのを知ったんだけど要は C++ の template だろーみたいな感じで触ってたら見事に違うことに気がついたのでちょいとまとめ。いやまぁ C++/CLI ていう文脈でまとめろよ的なアレもあるとは思うけどこういう視点のほうがわかりやすかったので。

とりあえず Generics てのは Microsoft が独自に定義した言葉らしく、 generic programming とは違うもの。あーでも違うつっても Generics ⊂ generic programming みたいな感じで型を data として扱う考え方が generic programming で Generics はそれの Microsoft 社による実装、みたいな。

でまぁ両者の違いを http://msdn.microsoft.com/en-us/library/sbh15dya.aspx を見つつまとめてみたという次第で。

  • C++ template
    • compile time に展開が行われる。
    • 上記から library なんかでは compile time に instantiation された型でないと外部から参照できない。
    • ひとつの instance ごとにひとつの codes が生成される。
    • 型以外の parameter を取ることができる。 template<int N> class A; が OK ということ。
    • 特殊化・部分特殊化を行うことができる。
    • template を用いて定義された class の base class をその type parameter に指定することができる。 ( ちょっとわけわからん。原文は Generics do not allow the type parameter to be used as the base class for the generic type. Templates do. comment で class Derived<TBase> : TBase {} という code が書けないと教えてもらった。たしかにできないんだけど、 error message が 'TBase' は型パラメーターであるため、派生させることはできません。とか出てきててなんか symbol 管理からくる制約ぽい気がする。 code の意味を考えると「 TBase を派生した class Derived が generic parameter TBase を持っている」という解釈が妥当な気がするんだけどな… )
    • nest できる。
  • C# Generics
    • runtime に展開が行われる。
    • 上記から library 化しても問題なく任意の型を instantiation しつつ外部から呼び出せる。
    • すべての instance はひとつの codes を共有するが、値型はひとつの instance がひとつの codes を生成する。
    • 型以外の parameter を取ることができない。 class A<int N> {} という考え方がない。
    • 特殊化・部分特殊化を行うことができない。
    • Generics を用いて定義された class の base class をその type parameter に指定することができない。 ( 上記でわけわからんていってたもう一方。 )
    • nest できない。

とまぁかなり違うもんだということがわかった。 Generics は code を書く上での柔軟性はないけど dll やらの library を作る際にも使えるというけっこうすごいこ。まぁ C++ でも template 使った library ぽいものは hpp で提供する、ということでできたりはするんだけど binary で配布できないのでこれは素直に advantage といえる。

うーん C# 意外におもしれーなぁ。どうせ ( 中略 ) と思ってたおれ反省したほうがいいな。