2011-12-07 6 views
1

一部の演算子のオーバーロードに問題があります。CRTPと他のテンプレートによる継承のオーバーロード

具体的には、伝統的なCRTP設定のDerived : public interface_mixin<Derived>を持つinterface_mixin<T>というテンプレートがあります。

今、私はオブジェクトであるが、他の側はテンプレートである、つまり、どちら側に演算子オーバーロードする必要があります。

template<typename T, typename Derived> ... operator.. 
(T t, const interface_mixin<Derived>& d) { 
    ... 
} 
template<typename T, typename Derived> ... operator.. 
(const interface_mixin<T>& t, Derived d) { 
    ... 
} 
template<typename T, typename Derived> ... operator.. 
(const interface_mixin<T>& t, const interface_mixin<Derived>& d) { 
    ... 
} 

しかし、私のコンパイラ(VS2010)があいまいなを呼び出して、これを受け入れることはありませんが過負荷。これらの過負荷を受け入れるように私にどのように説得することができますか?

今、SFINAEを使用して他のオーバーロードをクリアしようとしています。しかし、ロジックが正常に見えても、コンパイラは誤ったオーバーロードを選択します。

template<typename T, typename Derived> 
typename std::enable_if< 
    !std::is_base_of< 
     interface_mixin<T>, 
     T 
    >::value, 
    and< 
     equality_rule<T>, 
     Derived 
    > 
>::type operator>>(T t, const interface_mixin<Derived>& d) { 
    return and<equality_rule<T>, Derived>(equality_rule<T>(std::move(t)), d.crtp_cast()); 
} 
template<typename T, typename Derived> 
typename std::enable_if< 
    !std::is_base_of< 
     interface_mixin<Derived>, 
     Derived 
    >::value, 
    and< 
     T, 
     equality_rule<Derived> 
    > 
>::type operator>>(const interface_mixin<T>& t, Derived d) { 
    return and<T, equality_rule<Derived>>(t.crtp_cast(), equality_rule<Derived>(std::move(d))); 
} 
template<typename T, typename Derived> and<T, Derived> operator>>(const interface_mixin<T>& t, const interface_mixin<Derived>& d) { 
    return and<T, Derived>(t.crtp_cast(), d.crtp_cast()); 
} 

しかし、VSは、間違ったオーバーロードを選んでいると、間違った過負荷が選ばれたときの論理は意味がありません。

答えて

1

質問の最初の部分は第2の形式とは異なります。第2の部分では戻り型を指定しません。
戻り値の型がvoidある場合 - このコードは、私のMSVC2010コンパイラで動作します:

#include <iostream> 

template<class T> struct interface_mixin {}; 

template<typename T, typename Derived> 
typename std::enable_if<!std::is_base_of<interface_mixin<T>, T>::value, void>::type 
operator>>(T t, const interface_mixin<Derived>& d) { std::cout << "1\n"; } 

template<typename Derived, typename T> 
typename std::enable_if<!std::is_base_of<interface_mixin<T>, T>::value, void>::type 
operator>>(const interface_mixin<Derived>& d, T t) { std::cout << "2\n"; } 

template<typename DerivedL, typename DerivedR> 
void 
operator>>(const interface_mixin<DerivedL>& t, const interface_mixin<DerivedR>& d) 
{ std::cout << "3\n"; } 

struct Foo : interface_mixin<Foo> {}; 
struct Bar : interface_mixin<Bar> {}; 

int main() 
{ 
    Foo f; 
    Bar b; 

    1 >> f; 
    f >> 1; 
    f >> b; 
} 

問題は、戻り値の型や他の何かである場合、私は知らないが、enable_ifは、この問題を解決する必要があります。

+0

2番目の部分は、最初の部分で説明した問題を解決するための私の試みでした。奇妙なことに、独自のコードをコンパイルして正しい結果が得られました。第2の部分とあなたの答えの違いは分かりません。 – Puppy

+0

@DeadMG、この問題を再現する完全な最小限のコードを提供してください。 – Abyx

+0

私はそれを試みました。コードをコピーして貼り付け、3つのテストケースを実行したところ、うまくコンパイルされました。しかし、私の実際の使用コードは動作しません。 – Puppy

関連する問題