0

我需要创建一堆类,以便可以相互比较特定类型的实例。

我想写一个 compare 方法,每个类都是唯一的,然后将以下代码添加到每个类定义中,将 T 替换为我所在的类的名称:

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 上对其进行参数化,但是宏现在不是很 cplusplusy,是吗?我还考虑了继承和多态性,从我所读到的(我还没有使用虚拟类;我是 C++ 新手),我似乎会引入不必要的运行时开销,因为我m 不需要通过基类指针进行统一访问。除了宏或复制粘贴之外,还有更好的方法来完成它吗?

4

3 回答 3

1

Boost.Operators

标头<boost/operators.hpp>提供了几组类模板(在命名空间中boost)。这些模板根据类提供的最少数量的基本运算符在命名空间范围内定义运算符。

#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);
}
于 2013-04-20T22:51:32.327 回答
0

不使用升压:

#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 <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);
}
于 2013-04-20T23:00:44.583 回答
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 和所有后代。

于 2013-04-20T22:38:50.740 回答