简体   繁体   English

C ++大于或等于运算符

[英]C++ greater than or equal to operator

In C++, for the operator greater than or equal to (">="), is it enough to have the operators equal ("=") and greater (">") overloaded to have functionality for the greater than or equal to (">=")? 在C ++中,对于大于或等于(“> =”)的运算符,是否足以让运算符等于(“=”)和更大(“>”)重载以具有大于或等于的功能( “> =”)? Or do I need to overload the operator (">=") to have functionality for it? 或者我是否需要重载运算符(“> =”)以使其具有功能?

is it enough to have the operators equal ("=") 是否足以使运算符相等(“=”)

Equal operator in c++ is == c ++中的等于运算符是==

OR do I need to overload the operator (">=") to have functionality for it? 或者我需要重载运算符(“> =”)以使其具有功能吗?

It depends what you mean by functionality. 这取决于你的功能。 If you mean that if you define operator== and operator> will compiler generate operator>= automagically for you? 如果你的意思是,如果你定义operator==operator>编译器会为你自动生成operator>=吗? No, it would not, you have to implement it using existing operators or not. 不,它不会,你必须使用现有的运营商来实现它。

operator >= is not a combination of operator > and operator = . operator >=不是operator >operator =的组合。 operator >= is its own operator but you can implement it in terms of operator < Typically you would have something like 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);} 

From sbi's answer on What are the basic rules and idioms for operator overloading? 来自sbi的回答有关运算符重载的基本规则和习惯用法是什么?

No, C++ does not write those operators for you. 不,C ++不会为您编写这些运算符。

If you think that sucks, you are right. 如果你认为这很糟糕,那你就是对的。 A bunch of ways to make this suck less have been done. 已经完成了许多减少这种麻烦的方法。 I'll talk about 4 of them. 我会谈谈他们中的4个。

Wait for 等等

In , if you write operator<=> (the 3-way "spaceship" operator) properly, or =default it, then all of < , <= , >= , > , != and == will be written for you. ,如果正确地编写operator<=>3向 “太空飞船”运算符),或者=default运算符,那么<<=>=>!===都将是写给你的。

struct bob {
  int x,y;
  auto operator<=>( bob const& )const = default;
};

The above bob has every < == etc operator written for it by C++ now. 上面的bob现在有C ++为它编写的每个< == etc运算符。

Just write them 写下来吧

Prior to you have to write all of them if you want all of them. 之前,如果你想要所有这些,你必须编写所有这些。 This is tedious and error-prone. 这很乏味且容易出错。

Using std::tie and invoking < and the like on them is slightly less error-prone: 使用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);
  }
};

or even 甚至

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);
  }
};

because tuple does a proper lexographic comparison; 因为tuple了适当的词汇比较; writing lexographic comparions without bugs is annoying. 写没有错误的词汇比较令人讨厌。

Metaprogram your way around it 以它为中心的方式进行Metaprogram

When comparing strings you usually use strcmp . 比较字符串时,通常使用strcmp This returns a negative number if less, a positive number if greater, and 0 if equal. 如果更小则返回负数,如果更大则返回正数,如果相等则返回0。 This pattern can be more efficient than doing < or == repeatedly. 这种模式比重复执行<==更有效。

Making a single strcmp like function produce < == and the other comparison operations can be done: 制作单个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); }
  };
}

Now supose we have a type: 现在我们有一个类型:

struct bob {
  int x, y;
};

and we want to be able to use comparison operators on it: 我们希望能够在其上使用比较运算符:

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;
  }
};

and using the magic of CRTP bob now has every comparison operator written for it. 并且使用CRTP bob的魔力现在已经为它编写了每个比较运算符。

Live example . 实例

That annoying friend int cmp (which gets more annoying the more members you have in it) can be handled by yet more boilerplate helper code: 那个讨厌的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;
  }
}

which is yet more arcane code, but you get a simpler bob : 这是更神秘的代码,但你得到一个更简单的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) );
  }
};

Note, however, that all of this is done and better by operator<=> in . 但请注意,所有这些都是由 operator<=>完成的。

Live example . 实例

Use someone else's solution 使用别人的解决方案

This is similar to the approach boost::operators uses to write these operators for you. 这与boost ::运算符用于为您编写这些运算符的方法类似。

Using an obvious notation, " > || == " is actually an over-requirement for >= . 使用明显的表示法,“ > || == ”实际上是对>=的过度要求。

Although note that for all the relational operators, you only actually need < , since equivalence is established if a < b and b < a are both false. 虽然请注意,对于所有关系运算符,您实际上只需要< ,因为如果a < bb < a都为假,则建立等价。 In fact this is one of the concepts used in ordered C++ standard library containers. 实际上,这是有序C ++标准库容器中使用的概念之一。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM