0

SO には既に C++ のオーバーロードに関する質問が山ほどあると言いたいのですが、それらの質問やフォーラムやニュースグループの他の投稿を 1 時間見ても、まだ困惑しています。

バックグラウンド

名前空間を作成し、それを A と呼びます。ここでは、多数のクラスが同じ方法で < 演算子を実装しています。コードの重複を避けるために、私はこれを書きました:

namespace A{
     template<typename T>
     bool operator< (const T&, const T&);
}

operator_forwards.h というヘッダー ファイルで、他のいくつかの宣言を行います。次に、次のような行を追加して、正しいクラスの友達にしました。

//example.h
#include "operator_forwards.h"
namespace A{
    template<typename T>
    class Example{
        public:
        friend bool operator< <>(const Example<T>&, const Example T&);
        private:
        T start;
    };
} 

最後に、次のように、operators.h というファイルに定義を入れます。

namespace A{
    template<typename T>
    bool operator<(const T& lhs, const T& rhs){
        using std::operator<;
        return lhs.start<rhs.start;
    }
}

すべてを 1 つのヘッダー ファイルに含めます。

//A.h
#include "example.h"
#include "operators.h"

問題

問題は、次のように operator< を呼び出すときです。

Example<vector<int>::iterator> ex1(**foo**);
Example<vector<int>::iterator> ex2(**bar**);
ex1<ex2;

ex1.start<ex2.startA::operator< は問題なく呼び出しますが、vector::iterator のより特殊化された operator< を検索するのではなく、自分自身を再帰的に呼び出します。エラー C2039: start は vector::iterator のメンバーではありません。

A::operator< が ex1.start に対して正しい operator< を呼び出すことを確認するためのアドバイスはありますか?

注: A::operator< を使用する約 20 のクラスがあるため、各クラスで個別に定義することを避けることができれば、それは素晴らしいことです。

4

1 に答える 1

2

私の謙虚な提案:そうしないでください。

の実装よりも多くの場所でこの問題に対処する必要がありますA::operator<。どこにでもあるコードは、何かAをサポートしていると主張するこの予期しないテンプレートによって潜在的に混乱する可能性がありますが、実際にはメンバーoperator<を持つ型でのみ実行できます。start

あなたの場合、あなたはfriendどこにでも関連するすべてのクラスに宣言を置いています。それらのクラスに単純に実装するだけのコードはほとんどありません。それがコード重複の感度を損なう場合は、共有基本クラスを検討してください。

template <typename T>
class IterWrapper {
public:
    IterWrapper() {}
    explicit IterWrapper(T it) : start(it) {}

    bool operator< (const IterWrapper<T>& rhs) { return start < rhs.start; }
protected:
    T start;
};
于 2012-08-25T17:49:29.423 に答える