CLI/C++接口class,泛型方法调用模板方法
CLI/C++ Interface class, Generic method calling template method
我目前正在编写一个接口包装器 class 来构建一个桥梁
在托管代码和 c++ class 之间。由于此 c++ class 确实导出
模板方法我在调用它们时遇到了一些麻烦。我要曝光
一个通用方法,然后调用相应的模板方法。
在下面的示例中,我想公开调用 _AppendData 的 AppendData,
然后调用模板方法。
我收到 _AppendData 调用的编译错误:
错误 1 error C2664: 'void managedInterface::Channel::_AppendData(cli::array ^)' : 无法将参数 1 从 'cli::array ^' 转换为 'cli::array ^' d:\sources\something\SomeExports.h 421 1
我做错了什么?
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)
{
}
您的语法不起作用的原因很简单:泛型在运行时具体化,而模板在编译时实例化。这意味着 _AppendData(aArray);
的重载决策必须在编译时执行,但 aArray
的类型直到运行时才知道。这两种情况是不相容的。
恐怕没有比这更好的解决方案了:
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));
}
除了此代码由于 MSVC 错误而无法编译:/
error C2681: 'cli::array<T, 1> ^
': invalid expression type for dynamic_cast
所以我们必须解决这个问题:
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));
}
我目前正在编写一个接口包装器 class 来构建一个桥梁 在托管代码和 c++ class 之间。由于此 c++ class 确实导出 模板方法我在调用它们时遇到了一些麻烦。我要曝光 一个通用方法,然后调用相应的模板方法。
在下面的示例中,我想公开调用 _AppendData 的 AppendData, 然后调用模板方法。
我收到 _AppendData 调用的编译错误: 错误 1 error C2664: 'void managedInterface::Channel::_AppendData(cli::array ^)' : 无法将参数 1 从 'cli::array ^' 转换为 'cli::array ^' d:\sources\something\SomeExports.h 421 1
我做错了什么?
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)
{
}
您的语法不起作用的原因很简单:泛型在运行时具体化,而模板在编译时实例化。这意味着 _AppendData(aArray);
的重载决策必须在编译时执行,但 aArray
的类型直到运行时才知道。这两种情况是不相容的。
恐怕没有比这更好的解决方案了:
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));
}
除了此代码由于 MSVC 错误而无法编译:/
error C2681: '
cli::array<T, 1> ^
': invalid expression type fordynamic_cast
所以我们必须解决这个问题:
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));
}