オーバーライドされた等価演算子を使用して、同じインターフェイスのテンプレート実装を比較する際に問題があります。
Interface* ptr1 = ...; Interface* ptr2 = ...;
*ptr1 == *ptr2;
私が思いついた唯一の解決策は、同じように実装されたオブジェクトのみを比較し、次のような比較を実装することです。
class Interface {
public:
virtual ~Interface() {}
virtual bool operator==(const Interface&) const = 0;
};
template <typename T> class Impl : public Interface {
public:
bool operator==(const Interface& rhs) const {
assert(typeid(rhs) == typeid(const Impl&));
const Impl& rhsRef = static_cast<const Impl&>(rhs);
// ...
}
};
このソリューションの問題は、私の目的にはあまりにも制限されていることです。さまざまな実装を比較できるようにしたいと考えています。実装数が限られている場合は、ダブル ディスパッチ パターンを使用できます。しかし、私の場合、Impl はテンプレートであるため、仮想関数テンプレートが必要になるため、二重ディスパッチはできません。
// This obviously doesn't work.
class Interface {
public:
virtual ~Interface() {}
virtual bool operator==(const Interface&) const = 0;
template <typename T2> virtual bool operator==(const Impl<T2>&) const = 0;
};
template <typename T> class Impl : public Interface {
public:
bool operator==(const Interface& rhs) const {
return rhs == *this;
}
template <typename T2> bool operator==(const Impl<T2>& rhs) const {
// ...
}
};
解決策はありますか?これは、任意の STL イテレータをラップできる AnyIterator クラスを記述するために必要です。ただし、イテレーターと const_iterator など、異なる型にラップされている場合、AnyIterator を比較することはできません。
std::list<int>::iterator it1 = ...; std::list<int>::const_iterator it2 = ...;
AnyIterator<const int> myIter1 = it1; AnyIterator<const int> myIter2 = it2;
it1 == it2; // This works perfectly.
myIter1 == myIter2; // This doesn't work!