tags:

views:

1130

answers:

3

Hi,

I have the following class in C++/CLI and an explicit template instantiation for the int primitive..

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>;

On compiling this and inspecting the generated assembly using reflector I am able to see a class called Number<int> but while trying to instantiate this same class in C# the compiler complains about some System::Number class not taking a template argument. What am I doing wrong? Can this be done at all?

+3  A: 

I have a work around, declare an additional class inheriting the Number<int> class. This class is now visible in C# and can be instantiated.

public ref class MyInt32 : public Number<int>
{
};
SDX2000
A: 

If your goal is to create a parametrized type in C++ CLI, and then use that type from C#, I think that you need to create a generic type rather than a template type (see Stan Lippman's Blog for the reasons why both methods exist). See here for information on how to create generic types in C++ CLI.

Andy
Sadly, creating generic types defeats the whole purpose of using C++/CLI since C# can do the same and is equally ineffective.
SDX2000
Then it sounds like the answer you posted is the only way to go (even though that somewhat defeats the purpose of using templates, too). As @JaredPar said, templates are not the same as generics, and only C++ can use templates.
Andy
+4  A: 

Reflector is lying a little bit here. The name of the class is not actually Number<int>. It is actually 'Number<int>'. Notice the single quotes. These are only visible when you view the type name with ildasm.

I believe this is done to make the type unbindable in most languages as they have no way of understanding how a C++ template actually works. This makes it effectively only visible to the C++ compiler which is appropriate since it's the only MS compiler that actually supports templates (templates != generics).

JaredPar
And I think that C++/CLI templates have a required modifier on them as well, ildasm should show that as well. CLI prohibits tools who don't understand a required modifier to use the member.
Anton Tykhyy