C ++大于或等于运算符

时间:2018-09-06 13:49:09

标签: c++ operators overloading

在C ++中,对于大于或等于(“> =)的运算符,是否足以重载等于(” =“)和更大(”>“)的运算符以使其具有大于或等于的功能。等于(“> =”)?还是我需要重载运算符(“> =”)才能具有功能?

4 个答案:

答案 0 :(得分:12)

  

足以使运算符相等(“ =”)

c ++中的等于运算符为==

  

或者我是否需要重载运算符(“> =”)才能具有功能?

这取决于您对功能的含义。如果您的意思是,如果您定义operator==operator>,编译器会自动为您生成operator>=吗?不,不会,您必须使用现有的运算符来实现它。

答案 1 :(得分:11)

operator >=不是operator >operator =的组合。 operator >=是它自己的运算符,但您可以根据operator <来实现它,通常情况下,您会遇到类似的情况

inline bool operator==(const X& lhs, const X& rhs){ /* do actual comparison */ }
inline bool operator!=(const X& lhs, const X& rhs){return !operator==(lhs,rhs);}
inline bool operator< (const X& lhs, const X& rhs){ /* do actual comparison */ }
inline bool operator> (const X& lhs, const X& rhs){return  operator< (rhs,lhs);}
inline bool operator<=(const X& lhs, const X& rhs){return !operator> (lhs,rhs);}
inline bool operator>=(const X& lhs, const X& rhs){return !operator< (lhs,rhs);}

摘自answer上sbi的What are the basic rules and idioms for operator overloading?

答案 2 :(得分:11)

不,C ++不会为您编写这些运算符。

如果您认为很糟糕,那是对的。已经采取了许多减少这种吸吮的方法。我将讨论其中的四个。

等待

中,如果您正确编写operator<=>3-way“太空飞船”运算符)或=default,则<,{将为您编写{1}},<=>=>!=

==

上面的struct bob { int x,y; auto operator<=>( bob const& )const = default; }; 具有C ++现在为其编写的每个bob <等运算符。

只要写出来

之前,如果需要全部内容,则必须全部编写。这很繁琐且容易出错。

在它们上使用==并调用std::tie之类的错误发生的可能性略小:

<

甚至

struct bob {
  int x, y;
  friend bool operator<( bob const& lhs, bob const& rhs ) {
    return std::tie(lhs.x, lhs.y) < std::tie(rhs.x, rhs.y);
  }
};

因为struct bob { int x, y; friend auto as_tie( bob const& b ) { // C++14 return std::tie(b.x, b.y); } friend bool operator<( bob const& lhs, bob const& rhs ) { return as_tie(lhs) < as_tie(rhs); } }; 进行了正确的词典比较;编写没有错误的字典比较很烦人。

按照自己的方式进行元编程

比较字符串时,通常使用tuple。如果小于,则返回负数;如果大于,则返回正数;如果相等,则返回0。这种模式比重复执行strcmp<更为有效。

使单个类似==的函数产生strcmp <,其他比较操作可以完成:

==

现在,我们有一个类型:

namespace utils {
  template<class D>
  struct use_cmp {
    friend bool operator<( use_cmp<D> const& lhs, use_cmp<D> const& rhs ) {
      return cmp( lhs.self(), rhs.self() ) < 0;
    }
    friend bool operator>( use_cmp<D> const& lhs, use_cmp<D> const& rhs ) {
      return cmp( lhs.self(), rhs.self() ) > 0;
    }
    friend bool operator<=( use_cmp<D> const& lhs, use_cmp<D> const& rhs ) {
      return cmp( lhs.self(), rhs.self() ) <= 0;
    }
    friend bool operator>=( use_cmp<D> const& lhs, use_cmp<D> const& rhs ) {
      return cmp( lhs.self(), rhs.self() ) >= 0;
    }
    friend bool operator==( use_cmp<D> const& lhs, use_cmp<D> const& rhs ) {
      return cmp( lhs.self(), rhs.self() ) == 0;
    }
    friend bool operator!=( use_cmp<D> const& lhs, use_cmp<D> const& rhs ) {
      return cmp( lhs.self(), rhs.self() ) != 0;
    }
  private:
    D const& self() const { return *static_cast<D const*>(this); }
  };
}

,我们希望能够在其上使用比较运算符:

struct bob {
  int x, y;
};

并使用CRTP struct bob : utils::use_cmp<bob> { int x, y; bob( int x_, int y_ ):x(x_), y(y_) {} // constructor friend int cmp( bob const& lhs, bob const& rhs ) { if (lhs.x < rhs.x) return -1; if (lhs.x > rhs.x) return 1; if (lhs.y < rhs.y) return -1; if (lhs.y > rhs.y) return 1; return 0; } }; 的魔力为它编写了每个比较运算符。

Live example

烦人的bob(越多烦人的成员越多)可以通过更多样板帮助程序代码来处理:

friend int cmp

这是更多神秘的代码,但是您会得到一个更简单的namespace utils { template<class...Ts> int cmp( std::tuple<Ts...> const& lhs, std::tuple<Ts...> const& rhs ); template<class T, class...LowPriority> int cmp( T const& lhs, T const& rhs, LowPriority&&... ); template<class...Ts, std::size_t...Is> int tuple_cmp( std::tuple<Ts...> const& lhs, std::tuple<Ts...> const& rhs, std::index_sequence<Is...> ) { int result = 0; ( (result = cmp( std::get<Is>(lhs), std::get<Is>(rhs) )) && ... ); return result; } template<class...Ts> int cmp( std::tuple<Ts...> const& lhs, std::tuple<Ts...> const& rhs ) { return tuple_cmp( lhs, rhs, std::make_index_sequence<sizeof...(Ts)>{} ); } template<class T, class...LowPriority> int cmp( T const& lhs, T const& rhs, LowPriority&&... ) { if (lhs < rhs) return -1; if (rhs < lhs) return 1; return 0; } }

bob

但是请注意,中的struct bob : utils::use_cmp<bob> { int x, y; bob( int x_, int y_ ):x(x_), y(y_) {} friend auto as_tie(bob const& b) { return std::tie(b.x,b.y); } friend int cmp( bob const& lhs, bob const& rhs ) { return utils::cmp( as_tie(lhs), as_tie(rhs) ); } }; 可以更好地完成所有这些工作。

Live example

使用其他人的解决方案

这类似于boost::operators用来为您编写这些运算符的方法。

答案 3 :(得分:9)

使用明显的符号“ > || ==”实际上是对>=的超额要求。

尽管请注意,对于 all 而言,关系运算符实际上只需要<,因为如果a < bb < a均为假,则建立了等价关系。实际上,这是有序C ++标准库容器中使用的概念之一。