Reputation: 41
I am currently coding an interface wrapper class which builds a bridge between managed code and a c++ class. As this c++ class does export template methods i have some troubles calling them. I want to expose a generic method which then calls the corresponding template method.
In the example below, i want to expose AppendData, which calls _AppendData, which then calls the template method.
I am getting a compile error for the _AppendData call: Error 1 error C2664: 'void managedInterface::Channel::_AppendData(cli::array ^)' : cannot convert argument 1 from 'cli::array ^' to 'cli::array ^' d:\sources\something\SomeExports.h 421 1
What am i doing wrong?
generic <typename T> void AppendData ( array<T> ^aArray)
{
_AppendData(aArray);
}
internal:
void _AppendData(array<char> ^aArray);
void _AppendData(array<short> ^aArray);
void _AppendData(array<int> ^aArray);
void _AppendData(array<long long> ^aArray);
void _AppendData(array<unsigned char> ^aArray);
void _AppendData(array<unsigned short> ^aArray);
void _AppendData(array<unsigned int> ^aArray);
void _AppendData(array<unsigned long long> ^aArray);
void _AppendData(array<float> ^aArray);
void _AppendData(array<double> ^aArray);
template <typename T> void __AppendData(array<T> ^aArray)
{
}
Upvotes: 2
Views: 1007
Reputation: 51330
Your syntax does not work for a simple reason: generics are reified at runtime, while templates are instantiated at compile time. This means that overload resolution for _AppendData(aArray);
must be performed at compile time, but the type of aArray
won't be known until runtime. These two situations are incompatible.
I'm afraid there's no better solution than this:
generic <typename T> void AppendData(array<T>^ aArray)
{
if (dynamic_cast<array<char>^>(aArray) != nullptr)
{
_AppendData(safe_cast<array<char>^>(aArray));
return;
}
if (dynamic_cast<array<short>^>(aArray) != nullptr)
{
_AppendData(safe_cast<array<short>^>(aArray));
return;
}
// Do the same for the other ones
throw gcnew System::NotSupportedException(System::String::Format("Unsupported type: {0}", T::typeid));
}
Except this code won't compile because of a MSVC bug :/
error C2681: '
cli::array<T, 1> ^
': invalid expression type fordynamic_cast
So we'll have to work around this:
template <class T> bool is_instance_of(System::Object^ obj)
{
return dynamic_cast<T>(obj) != nullptr;
}
generic <typename T> void AppendData(array<T>^ aArray)
{
if (is_instance_of<array<char>^>(aArray))
{
_AppendData(safe_cast<array<char>^>(aArray));
return;
}
if (is_instance_of<array<short>^>(aArray))
{
_AppendData(safe_cast<array<short>^>(aArray));
return;
}
// Do the same for the other ones
throw gcnew System::NotSupportedException(System::String::Format("Unsupported type: {0}", T::typeid));
}
Upvotes: 5