재정의 된 동등성 연산자를 통해 동일한 인터페이스의 템플릿 구현을 비교하는 데 문제가 있습니다.지우기 및 상호 운용성 유형 : C++의 가상 이진 연산자 문제
Interface* ptr1 = ...; Interface* ptr2 = ...;
*ptr1 == *ptr2;
I가 와서 한 유일한 솔루션은 동일하게 구현 객체를 비교할 수 있으며이 같은 비교를 구현하는 것을 강제하는 것입니다
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 {
// ...
}
};
모든 솔루션은 거기에 있습니까? Any STL iterator를 래핑 할 수있는 AnyIterator 클래스를 작성해야합니다. 서로 다른 유형의 주위에 감싸 인 경우하지만 예를 들어 반복자와 const_iterator를 들어, AnyIterators을 비교할 수 없습니다 :
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!
필자가 마지막 섹션에서 썼 듯이, 다른 STL 반복자를 감싸는 AnyIterator를 비교하기 위해이 항목이 필요합니다. AnyIterator에는 iterator 인터페이스에 대한 포인터가 들어 있으며,이 포인터는 보유하고있는 STL 반복자의 유형에 따라 다르게 구현할 수 있습니다. 따라서 인터페이스에서 연산자 ==를 선언하지 않고도 비교를 구현할 수있는 가능성은 없습니다. – lizarisk
@lizarisk : 두 개의 std :: vector :: iterator를 비교할 수 있다고 생각조차 할 수 없습니다. 그들은 같은 벡터를 지적해야합니다. 두 컨테이너의 반복자를 비교하는 것은 UB입니다. 이러한 기능을 추가해야하는 경우 원래 컨테이너를 저장해야합니다. 'void *'로 저장하면 두 반복자가 같은 컨테이너에서 왔는지 먼저 확인해 볼 수 있습니다. 그렇다면, 근본적인 타입은 하나 뿐이며, 그렇지 않으면 즉시'false'를 반환합니다. –
MSalters