2012-01-05 1 views
3

Xでのメソッドテストが曖昧で、なぜこれを修正できますか?関数のオーバーロードでタグを使用する

struct A{}; 
struct B{}; 

template<typename T> 
struct I { void test(T){} }; 
struct X : public I<A>, I<B> {}; 

int main(int argc, const char *argv[]) 
{ 
    X x; 
    x.test(A()); 
    return 0; 
} 

コンパイルエラー:それはX二基底クラスのメンバーであるため

In function ‘int main(int, const char**)’: 
error: request for member ‘test’ is ambiguous 
error: candidates are: void I<T>::test(T) [with T = B] 
error:     void I<T>::test(T) [with T = A] 
+0

現在のコードがあいまいでコンパイルされていないこと、このコードがあいまいさを修正しているが、スタイルが気に入らないことをお勧めしますか? – Useless

+0

@Useless、私は明確にするために少し質問を精緻化しました – Allan

答えて

6

testがあいまいです。両方の機能が一致するわけではありませんが、という名前はと一致します。明示的な前進と

修正:

struct X : public I<A>, I<B> { 
    template <typename T> 
    void test(T t) { I<T>::test(t); } 
}; 
+1

+1ええ、これは行く方法です。私の答えよりもはるかにユーザーフレンドリー。 –

+0

@ ltn100:ありがとう、私はPlasmaHHの「使用する」方がさらに好きです。 :-) – thiton

+0

少し読みやすくなりますが、新しいベースクラスごとに新しいusingステートメントを追加する必要があります。私は多重継承の提唱者ではありませんが、それはOPが後にある機能だと思われます。 –

1

X乗算がI<A>I<B>から継承するので、test()への呼び出しはあいまいです。使用

struct A{}; 
struct B{}; 

template<typename T> 
struct I { void test(T){} }; 
struct X : public I<A>, I<B> {}; 

int main(int argc, const char *argv[]) 
{ 
    X x; 
    x.I<A>::test(A()); 
    return 0; 
} 
3

用途:

struct A{}; 
struct B{}; 

template<typename T> 
struct I { void test(T){} }; 
struct X : public I<A>, I<B> 
{ 
    using I<A>::test; 
    using I<B>::test; 
}; 

int main(int argc, const char *argv[]) 
{ 
    X x; 
    x.test(A()); 
    return 0; 
} 

をgccのエラーrequest for member 'test' is ambiguousが本当にここに最善ではない、我々が何を意味するかよりよく見ることができますあなたは明示的に言及されている親宣言するためにこれを行うことができますclangのエラー:member 'test' found in multiple base classes of different types

+0

thitonの転送方法は、100個のステートメントを使用するのではなく、10個の転送機能を記述することを意味します。 – Useless

+0

@Useless:OPの質問は、どのソリューションが本当に良いかを選択するために特定されていません。本当の問題がより複雑な/異例の型を転送する必要があるならば、C++ 11が "完全な転送"と呼ぶものをもっと注意深く、少なくとも使用する必要があります。しかし、その場合でも、オーバーロードが関数ポインタを受け取り、オーバーロードされた関数をテスト関数に渡すと、転送は選択された関数パラメータに一致するオーバーロードを持つのに役立ちません。 – PlasmaHH

関連する問題