1

C# プロジェクトでは、次のような型があります。

public struct Struct<T> { public T Field; }
public interface IInterface<T>
{
    T F(T x);
}
public abstract class Class<T> : IInterface<T>, IInterface<Struct<T>> {
    virtual public T F(T x) { return x; }
    virtual public T F(Struct<T> x) { return x.Field; }
    Struct<T> IInterface<Struct<T>>.F(Struct<T> x) { return default(Struct<T>); }
}

C++/CLI プロジェクトで、仮想メソッドを継承しClass<T>てオーバーライドしたい:F

public ref class Derived sealed : public Class<int> {
public:
    virtual int F(Struct<int> x) override;
};

残念ながら、これはうまくいきません:

error C2553: 'int Derived::F(Struct<T>)': overriding virtual function return type
differs from 'Struct<T> IInterface<Struct<T>>::F(Struct<T>)'
with
    [
        T=int
    ]

そのため、コンパイラは仮想メソッドではなく明示的なインターフェイスの実装をオーバーライドしたいと考えているようです。

いくつかのバリエーションを試しましたが、どれも機能しません。時々私はただ得ます

error C3671: 'Derived:F' : function does not override 'IInterface<T>::F'

オーバーライドする正しいメソッドを指定するにはどうすればよいですか?

アップデート

IInterface::FKen が以下で提案するように、明示的なインターフェイスの実装を追加すると、エラー メッセージが表示されなくなります。

これは C++/CLI コンパイラのバグのようです。インターフェイスを再実装する必要はありません。

残念ながら、回避策としては良いスタートですが、問題が完全に解決されたわけではありません。

Derived::Fとして呼び出すとIInterfaceDerivedの明示的な実装 ( IInterface_F) が呼び出されます。基本クラスから実装に呼び出しを渡すことができれば、これは回避策としては問題ありません。

したがって、次の質問は次のとおりです。同じシグネチャ (戻り値の型を除く) を持つオーバーロードがあり、派生クラスで同じインターフェイスの明示的な実装も定義している場合、基底クラスから明示的なインターフェイスの実装を呼び出すにはどうすればよいでしょうか?

言い換えれば、C# を使用している場合:

public interface IInterface {
    int F(int x);
}
public class A : IInterface {
    virtual long F(int x) { return 1L; }
    int IInterface.F(int x) { return 3; }
}

C++/CLI の場合:

public ref class B : A {
public:
    virtual long F(int x) override { return 2L; }        
    virtual int IInterface_F(int x) sealed = IInterface::F {
        return ??? // call A's version of IInterface::F(x), which returns three
    }
}

fromAのバージョンを呼び出すにはどうすればよいですか?IInterface::FIInterface_F

4

1 に答える 1

1

あなたが提供したコードで(Class<T>私には奇妙に見えますが):

public ref class Derived sealed : public Class<int> {
public:
    virtual int F(Struct<int> x) override;
};

コンパイラは不平を言います:

エラー C2553: 'int Derived::F(Struct)': 仮想関数の戻り値の型のオーバーライドが 'Struct IInterface>::F(Struct)' と異なります

    と
    [
        T=整数
    ]

エラー C3766: 'Derived' は、インターフェイス メソッド 'Struct IInterface>::F(Struct)' の実装を提供する必要があります

    と
    [
        T=整数
    ]

エラー C3612: 'Derived': シールされたクラスは純粋な仮想メソッドを持つことはできません 次のメソッドを定義する必要があります:

    'Struct IInterface>::F(Struct)' : 抽象です
    と
    [
        T=整数
    ]

したがって、コンパイラが問題を解決するだけだと言っているので、インターフェイスメソッドの実装を提供すると思います。

public ref class Derived sealed : public Class<int> {
public:
    virtual Struct<int> IInterface_F(Struct<int> x) 
        sealed=IInterface<Struct<int>>::F {
        return Struct<int>(); // equivalent to default(Struct<int>) in c#
    }

    virtual int F(Struct<int> x) override {
        return 0; // equivalent to default(int) in c#
    }
};
于 2013-06-10T02:35:04.730 に答える