0

C++ Primerは私たちにそうoperator<あるべきだと言っていることを覚えていますnon-member function、そして私は常に規則に従います。でも今はその理由を知りたいです。

私は次のコードを書きました:

#include <iostream>
using std::cout;
using std::endl;

struct Point1
{
  int x, y;
  Point1(const int a, const int b): x(a), y(b) { }
};
inline bool operator<(const Point1& lhs, const Point1& rhs)
{
  return lhs.x < rhs.x || (lhs.x == rhs.x && lhs.y < rhs.y);
}

struct Point2
{
  int x, y;
  Point2(const int a, const int b): x(a), y(b) { }
  bool operator<(const Point2& rhs)
  {
    return x < rhs.x || (x == rhs.x && y < rhs.y);
  }
};

int main()
{
  Point1 a(1, 2), b(1, 3);
  cout << (a < b) << " " << (b < a) << endl;
  Point2 c(2, 3), d(2, 4);
  cout << (c < d) << " " << (d < c) << endl;
}

この場合、違いはなく、member機能ははるかに単純なようです。

しかし、この場合:

#include <iostream>
using std::cout;
using std::endl;

 // Usually I write it for comparing floats
class Float1
{
  long double _value;
public:
  static const long double EPS = 1e-8;
  Float1(const long double value): _value(value) { }
  const long double Get() const { return _value; }
};
inline bool operator<(const Float1& lhs, const Float1& rhs)
{
  return rhs.Get() - lhs.Get() > Float1::EPS;
}
inline bool operator<(const Float1& lhs, const long double rhs)
{
  return rhs - lhs.Get() > Float1::EPS;
}

class Float2
{
  long double _value;
public:
  static const long double EPS = 1e-8;
  Float2(const long double value): _value(value) { }
  const long double Get() const { return _value; }
  bool operator<(const Float2& rhs)
  {
    return rhs._value - _value > Float2::EPS;
  }
  bool operator<(const long double rhs)
  {
    return rhs - _value > Float2::EPS;
  }
};

int main()
{
  Float1 x(3.14);
  Float2 y(2.17);
  long double zero = .0;
  cout << (x < zero) << " " << (zero < x) << endl;
  //cout << (y < zero) << " " << (zero < y) << endl; Compile Error!
}

(x <ゼロ)と(ゼロ<x)の両方が機能します!(?にlong double変換されFloatます)

ただし、ゼロは。ではないため、(ゼロ<y)はそうではありませんFloat

最初のケースでは、member functionコードの長さが短くなり、2番目のケースでnon-member functionは比較が容易になります。だから知りたい

  • 最初のケースでは、member function代わりに使用する必要がありnon-member functionますか?
  • なぜC++ Primer提案するbinary operatornon-member functionですか?
  • member function他に違いを生むケースはありますnon-member functionか?

助けてくれてありがとう!

4

3 に答える 3

5

基本的な答えは、非メンバー関数は暗黙の変換でよりうまく機能するということだと思います。したがって、二項演算子を非メンバー関数として記述できる場合は、そうする必要があります。

于 2012-08-21T01:01:03.053 に答える
3

質問はさまざまなレベルで答えることができます。設計上の観点から、最上位レベルoperator<は二項演算子です。右側にある操作は左側にあるということではありません。一方、メンバー関数は最初の引数にバインドされ、最初の型に対する操作です

技術的な観点から、そして C++ 言語に直行すると、これは既にお気づきのことになります: メンバー関数は型に関して対称的ではありません。この対称性の欠如はoperator<、メンバー関数として宣言された は、左側がメンバーを含む型である場合にのみ適用できることを意味します。メンバー演算子が呼び出される前に変換を適用することはできません。一方、free 関数は 2 番目の引数よりも最初の引数にバインドされていないため、 2 つの引数のいずれかが適切な型である場合はoperator<常に、free 関数が ADL によって取得され、 1 番目と 2 番目の引数。

于 2012-08-21T02:19:24.687 に答える
2

非メンバーとして、比較演算子は派生クラス(左側)の引数に対しても機能します。


編集:そして@jonathanがコメントで指摘しているように、int左側の引数などの値の変換も可能です。

コンストラクターと変換演算子がそうでない場合、そのような変換により、インスタンスを5explicitと比較するなど、意味のない、おそらく意図しないコードが許可される可能性があります。T

于 2012-08-21T01:01:27.607 に答える