2013-04-20 1 views
0

특정 유형의 인스턴스를 서로 비교할 수 있도록 여러 클래스를 만들어야합니다.코드에서 반복성을 피하면서 여러 C++ 클래스를 비교할 수있게 만들기

bool operator== (const T& L, const T& R)  {return L.compare(R)==0;} 
bool operator!= (const T& L, const T& R)  {return L.compare(R)!=0;} 
bool operator< (const T& L, const T& R)  {return L.compare(R)<0;} 
bool operator<= (const T& L, const T& R)  {return L.compare(R)<=0;} 
bool operator> (const T& L, const T& R)  {return L.compare(R)>0;} 
bool operator>= (const T& L, const T& R)  {return L.compare(R)>=0;} 

이는 다음과 같습니다

는 내가에있어 클래스의 이름으로 T를 교체, 각 클래스에 고유 비교 방법을 작성하고 각 클래스 정의에 다음 코드를 추가하는 방법에 대한 생각 그러나 반복적 인 종류. 더 일반적인 방법이 있습니까? 나는 그것을 위해 매크로를 작성할 수 있다고 생각합니다. T에서 그것을 매개 변수로 만들었지 만, 매크로는 지금 매우 복잡하지 않습니다. 그렇죠? 나는 또한 상속과 다형성에 대해 생각하고 그것에 대해 읽은 것에서 (아직 가상 클래스를 사용하고 있으며 C++을 처음 접했을 뿐이다.) 불필요한 런타임 오버 헤드를 도입하는 것처럼 보인다. 기본 클래스 포인터를 통해 유니폼에 액세스 할 필요가 없습니다. 매크로 또는 복사하여 붙여 넣기 이외의 다른 방법을 수행하는 더 좋은 방법이 있습니까?

+0

@tacp,하지만 좋은 템플릿 기반을 마련 할 수 없습니다 솔루션 그래서 나는 경험이 많은 C++ 코더에게 그것이 실제로 어떻게 이루어 졌는지 묻고 싶다고 생각했다. – PSkocik

답변

0

가장 가까운 곳은 기본 클래스에 대한 연산자를 제공하고 모든 비슷한 클래스를 상속받을 것을 요구하는 것입니다. 템플릿 멤버 함수로 구현하는 것은 컴파일러에 관심이보다 단지 종류의 조작을 시도 할 수 정확히 좋은 생각이 아니다.

class AClass 
{ 
public: 
    int compare(const AClass& a) const 
    { 
     return this == &a ? 0 : 1; // i'm sure you can do the -1/1 stuff 
    } 

    friend bool operator==(const AClass& L, const AClass& R) 
    { 
     return L.compare(R) == 0; 
    } 
}; 

이 AClass 모든 decendents의 비교를 허용 할 것이다 .

1

Boost.Operators

헤더 <boost/operators.hpp>은 (네임 스페이스 boost에서) 클래스 템플릿의 여러 세트를 제공합니다. 이 템플릿은 클래스가 제공하는 최소한의 기본 연산자의 측면에서 네임 스페이스 범위의 연산자를 정의합니다.

#include <cassert> 
struct Integer 
{ 
    int value; 
    Integer(int x) : value(x) {} 
}; 

bool operator<(Integer lhs,Integer rhs) 
{ 
    return lhs.value < rhs.value; 
} 
bool operator==(Integer lhs,Integer rhs) 
{ 
    return lhs.value == rhs.value; 
} 

template< class T > 
bool operator!= (const T& L, const T& R) { return !(L==R); } 
template< class T > 
bool operator<= (const T& L, const T& R) { return (L < R) || (L == R); } 
template< class T > 
bool operator> (const T& L, const T& R) { return (!(L < R)) && (!(L == R)); } 
template< class T > 
bool operator>= (const T& L, const T& R) { return !(L < R); } 

int main() 
{ 
    Integer a(1), b(2), c(1); 
    assert(a < b); 
    assert(a <= b); 
    assert(b > a); 
    assert(b >= a); 
    assert(a == c); 
    assert(a != b); 
} 

아니면 원래의 질문에 가까이 :

#include <boost/operators.hpp> 
#include <cassert> 

struct Integer : boost::totally_ordered<Integer> 
{ 
    int value; 
    Integer(int x) : value(x) {} 
}; 

bool operator<(Integer lhs,Integer rhs) 
{ 
    return lhs.value < rhs.value; 
} 
bool operator==(Integer lhs,Integer rhs) 
{ 
    return lhs.value == rhs.value; 
} 

int main() 
{ 
    Integer a(1), b(2), c(1); 
    // We have defined only operator< and operator== 
    assert(a < b); 
    assert(a == c); 
    // Other operators are provided automaticly: 
    assert(a <= b); 
    assert(b > a); 
    assert(b >= a); 
    assert(a != b); 
} 
0
부스트 사용하지 않고

내가 가진

#include <cassert> 
struct Integer { 
    int value; 
    Integer(int x) : value(x) {} 
    int compare(const Integer & rhs) const { 
    return (value - rhs.value); 
    } 
}; 

template< class T > 
bool operator== (const T& L, const T& R) { return L.compare(R)==0; } 
template< class T > 
bool operator!= (const T& L, const T& R) { return L.compare(R)!=0; } 
template< class T > 
bool operator< (const T& L, const T& R) { return L.compare(R)<0; } 
template< class T > 
bool operator<= (const T& L, const T& R) { return L.compare(R)<=0; } 
template< class T > 
bool operator> (const T& L, const T& R) { return L.compare(R)>0; } 
template< class T > 
bool operator>= (const T& L, const T& R) { return L.compare(R)>=0; } 

int main() { 
    Integer a(1), b(2), c(1); 
    assert(a < b); 
    assert(a <= b); 
    assert(b > a); 
    assert(b >= a); 
    assert(a == c); 
    assert(a != b); 
} 
+1

이 접근 방식의 단점은 내장 유형 및 기타 유형 (그리고 잘못된 사용에 대한 컴파일러 오류 오류 페이지)에 대해 잠재적으로 상충되는 연산자를 도입 한 것입니다. 대신에 연산자 템플릿이 정의 된 '템플릿 클래스'를 제안 할 것을 제안합니다. 사용법은 기이하게 반복되는 템플릿 패턴을 따릅니다. 즉 What Boost가 운영자 라이브러리를 제공합니다. –