初めてのC++/CLIその4
templateとgenericsの比較。genericsはよくtemplateみたいなものと紹介されますが、実際のところtemplateに比べると出来ることはかなり限定されています。なので、boostみたいなライブラリをこさえてやるぜ!みたいなこと考えているとガッカリします。(^^; 以下、簡単な比較サンプル。
#include "stdafx.h" using namespace System; using namespace stdcli::language; // 単純な例ではtemplateもgenericも見た目は一緒 template <typename T> ref class TClass1 { public: T t; }; // ただし、templateはコンパイル時、genericは実行時なことに注意 generic <typename T> ref class GClass1{ public: T t; }; // templateは型以外もパラメータに指定できる template <typename T, typename int U=10> ref class TClass2 { public: T* pt; TClass2() { pt = new T[U]; } }; /* genericは型以外をパラメータと出来ない generic <typename T, typename int U=10> ref class GClass2 { public: T* pt; GClass2() { pt = new T[U]; } }; */ ref class Class1 { public: // templateのパラメータは名前ベースなのでコンパイルは通る // コンパイル時に実体化された型がoperator+=を持っていればOK template <typename T> T Sum(array<T>^ arr) { T sum = 0; for (int i = 0; i < arr->Length; ++i) sum += arr[i]; return sum; } }; ref class Class2 { public: // genericは実行時に型パラメータ解決するので、 // Tに対するインタフェースは保証されていなければならない // Tはoperator+=を必ず持つわけでないのでコンパイルエラー。 /* generic <typename T> T Sum(array<T>^ arr) { T sum; for (int i = 0; i < arr->Length; ++i) sum += arr[i]; return sum; } */ }; // templateの中にgenericはOK template <typename T> ref class TClass3 { generic <typename U> void Hello() { Console::WriteLine(U); } }; // genericの中にtemplateはNG /* generic <typename T> ref class GClass3 { template <typename U> void Hello() { Console::WriteLine(U); } }; */ int _tmain() { TClass1<int>^ tc1i = gcnew TClass1<int>; GClass1<int>^ gc1i = gcnew GClass1<int>; TClass1<String^>^ tc1s = gcnew TClass1<String^>; GClass1<String^>^ gc1s = gcnew GClass1<String^>; TClass2<int, 5>^ tc2i = gcnew TClass2<int, 5>; Class1^ c1 = gcnew Class1; c1->Sum(gcnew array<int>{1,2,3,4,5}); }
パラメータに型しか渡せないこととや、genericな型に対するメソッド呼び出しをするにはwhereでインタフェースを明示的に書いてあげる必要があり、それだとgenericの必要性がないとか、結局のところコンテナ以外で活躍することは少ない気がします。まぁ、それで十分なんですがtemplateを知っているとちょっと寂しいです。
取りあえず、C++/CLIについては一旦終了です。