实现多个接口时如何处理函数名冲突?

How to handle conflicting function names when implementing multiple interfaces?

我在 C# 中定义了一个实现 IEnumerable 的接口。接口的实现将在 C++/WinRT 中完成,因为它需要直接访问本机代码。当我尝试使用 C++/WinRT 实现此接口时,生成的 header/implementation 包含两个具有不同 return 类型的 'First()' 函数(一个来自 IIterable,一个来自 IBindableIterable)。显然这不会编译。

有什么方法可以 "rename" IDL 文件中的一个(或两个)冲突函数? C++/CX 有一个解决方法,允许您使用不同的函数名称,然后 'bind' 返回接口名称。

下面的简化示例代码:

接口:

public interface IUInt32Array : IEnumerable<uint> {}

IDL:

[default_interface]
runtimeclass UInt32Array : IUInt32Array
{
    UInt32Array(UInt32 size);
}

生成的 IDL Header:

struct UInt32Array : UInt32ArrayT<UInt32Array>
{
    UInt32Array(uint32_t size);
    Windows::Foundation::Collections::IIterator<uint32_t> First();  // <-- Problem
    Windows::UI::Xaml::Interop::IBindableIterator First();          // <-- Problem
}

此特定问题的解决方案是使用 'auto' 的组合作为 First() 函数实现的已声明 return 类型,并使用 return 具有转换的类型两种不同 return 类型的运算符。

这里 example 展示了 CppWinRT 源代码是如何解决这个问题的。链接的源代码是针对 base_collections_vector.h header 的,具体参见 convertible_observable_vector::First() 函数(复制如下)。

    auto First() {
        struct result {
            container_type* container;

            operator wfc::IIterator<T>() {
                return static_cast<base_type*>(container)->First();
            }

            operator wfc::IIterator<Windows::Foundation::IInspectable>() {
                return make<iterator>(container);
            }
        };
        return result{ this };
    }

注意这里函数本身被定义为returning auto,这允许我们return一个中间类型。这个中间类型然后实现转换运算符以转换为调用者期望的类型。这适用于此特定问题,因为生成的 CppWinRT 源代码会立即将调用结果分配给预期类型的​​值,从而立即导致调用转换运算符,进而 return 最终正确的迭代器类型。

感谢 Kenny Kerr 向我指出 examplewrite-up 对上述内容的解释。