ユーザ用ツール

サイト用ツール


サイドバー

C++/CLI

CLR

実用編

その他

cli:generics

generics

genericsはC++のテンプレートと同じようなものです。テンプレートの場合、型の解決は実際のコード中でそのテンプレートが利用されるときに行われますが、genericsではgenericを使ったクラスがあった場合、そのクラスを使うコードがなくてもコンパイルできなければなりません。実行時に動的にそのgenericsを利用可能にするためです。そのため以下のような問題があります。

以下のようなC++のテンプレートを考えます。

class C {
public:
    int func() {
        return 1;
    }
};
template<typename T> class Caller {
public:
    int DoFunc(T& t) {
        return t.func();
    }
};
int main()
{
    C c;
    Caller<C> caller;
    int i = caller.DoFunc(c);
    return 0;
}

これをC++/CLIのgenericsを使って書くと以下のようになり、コンパイルエラーとなります。

ref class C {
public:
    int func() {
        return 1;
    }
};
generic<typename T> ref class Caller {
public:
    int DoFunc(T t) {
        return t->func();    // error
    }
};
int main()
{
    C^ c = gcnew C;
    Caller<C^>^ caller = gcnew Caller<C^>;
    int i = caller->DoFunc(c);
    return 0;
}

型Tはコンパイル時に解決しないため、Object型としかみなせないためです。そのためgenericsでは以下のような方法を利用します。

interface class I {
    int func();
};
ref class C : I {
public:
    virtual int func() {
        return 1;
    }
};
generic<typename T> where T : I ref class Caller {
public:
    int DoFunc(T t) {
        return t->func();
    }
};
int main()
{
    C^ c = gcnew C;
    Caller<C^>^ caller = gcnew Caller<C^>;
    int i = caller->DoFunc(c);
    return 0;
}

インターフェースIを利用して、型Tに縛りをかけます。

その他の注意点として、genericの型はハンドルか値型でなければなりません。




/var/www/html/virtual/cppcli/data/pages/cli/generics.txt · 最終更新: 2013/12/23 09:08 (外部編集)