9

C++/CLI に次のクラスがあり、int プリミティブの明示的なテンプレートのインスタンス化があります。

template<typename T>
public ref class Number
{
    T _value;
public:
    static property T MinValue
    {
        T get()
        {
            return T::MinValue;
        }
    }

    static property T MaxValue
    {
        T get()
        {
            return T::MaxValue;
        }
    }

    property T Value
    {
        T get()
        {
            return _value;
        }

        void set(T value)
        {
            if( value<MinValue || value > MaxValue)
                throw gcnew System::ArgumentException("Value out of range");

            _value = value;
        }
    }

};

template ref class Number<int>;

これをコンパイルし、リフレクターを使用して生成されたアセンブリを検査すると、呼び出されたクラスを確認できますNumber<int>が、C# でこの同じクラスをインスタンス化しようとすると、コンパイラーは一部のSystem::Numberクラスがテンプレート引数を取らないと文句を言います。私は何を間違っていますか?これはまったくできますか?

4

3 に答える 3

12

クラスを継承する追加のクラスを宣言するという回避策がありNumber<int>ます。このクラスは C# で表示され、インスタンス化できるようになりました。

public ref class MyInt32 : public Number<int>
{
};
于 2009-03-25T13:47:32.100 に答える
10

ここにリフレクターが少し横たわっています。クラスの名前は、実際には Number<int> ではありません。実際には 'Number<int>' です。一重引用符に注意してください。これらは、ildasm でタイプ名を表示する場合にのみ表示されます。

これは、C++ テンプレートが実際にどのように機能するかを理解する方法がないほとんどの言語で型をバインドできないようにするために行われると思います。これにより、実際にテンプレート (テンプレート != ジェネリック) をサポートする唯一の MS コンパイラであるため、適切な C++ コンパイラにのみ効果的に表示されます。

于 2009-03-25T13:58:47.797 に答える
1

C++ CLI でパラメーター化された型を作成し、C# からその型を使用することが目標である場合、テンプレート型ではなくジェネリック型を作成する必要があると思います (両方の方法が存在する理由については、Stan Lippman のブログを参照してください)。C++ CLI でジェネリック型を作成する方法については、こちらを参照してください。

于 2009-03-25T13:48:45.793 に答える