2

次の例と別の質問から取った例で、これが機能しない理由を理解しています。

struct Foo {
    Foo() {}
    Foo(int) {}
    Foo operator+(Foo const & R) { return Foo(); }
};


struct Bar {
    Bar() {}
    Bar(int) {}
};

Bar operator+(Bar const & L, Bar const & R) {
    return Bar();
}


int main() {
    Foo f;
    f+1;  // Will work - the int converts to Foo
    1+f;  // Won't work - no matching operator
    Bar b;
    b+1;  // Will work - the int converts to Bar
    1+b;  // Will work, the int converts to a Bar for use in operator+

}

しかし、このようにテンプレートを使用するように変更すると、次のようになります。

template <class T>
struct Foo {
    Foo() {}
    Foo(T) {}
    Foo operator+(Foo const & R) { return Foo(); }
};


template <class T>
struct Bar {
    Bar() {}
    Bar(T) {}
};

template <class T>
Bar operator+(Bar const & L, Bar const & R) {
    return Bar();
}


int main() {
    Foo<int> f;
    f+1;  // Will work - the int converts to Foo
    1+f;  // Won't work - no matching operator
    Bar<int> b;
    b+1;  // DOES NOT WORK
    1+b;  // DOES NOT WORK

}

それは動作しません。誰でもこれに光を当てることができますか?テンプレートは私を夢中にさせています。

ありがとう。

4

2 に答える 2

3

2 つの問題があります。

  1. 演算子の定義の引数にテンプレート タイプを追加する必要があります。これは、使用する Bar のインスタンス化を知るためにそれらを使用する必要があるため必要です。
  2. テンプレート関数で混合演算子 (2 つの別々の型で動作する) が必要な場合は、すべての混合ケースの定義を提供する必要があります。そうしないと、テンプレート控除システムが思いどおりに機能しません。

.

template <class T>
Bar<T> operator+(Bar<T> const & L, Bar<T> const & R) { // Fixed
    return Bar<T>();
}

template <class T>
Bar<T> operator+(Bar<T> const & L, const T & R) { // Added
    return L + Bar<T>(R);
}


template <class T>
Bar<T> operator+(const T& L, Bar<T> const & R) { // Added
    return Bar<T>(L) + R;
}
于 2012-07-17T20:28:55.320 に答える
1

との間には暗黙的な変換はなく、intBarの間だけです。実際、 type を定義していません。の代わりに、さまざまな値の型のファミリがあります。の定義に関連するコンパイラ エラーが表示されている可能性がありますが、他のテンプレート タイプのエラーの背後に隠れている可能性があります。intBar<int>BarBar<T>Toperator+

目の前に C++ コンパイラはありませんが、template<class T> Bar<T> operator+(Bar<T> const & L, Bar<T> const & R)期待どおりに動作すると思います。

于 2012-07-17T20:27:11.163 に答える