初めての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については一旦終了です。