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