質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

1回答

1309閲覧

ベクトルにオブジェクトを含む際に、何故関係演算子(<,==)のオーバーロードが必要なのか

iwanami

総合スコア9

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2020/05/29 06:18

編集2020/05/29 06:20

以下のプログラムは、ある参考書に載っているものです。

コード中に示した(あ)(い)の部分に関係演算子(<,==)のオーバーロードがされてあるんですが、
何故これが必要なのか分かりません。

本には、「他の演算子も定義しなければならないことがある。(一部省略)」とだけ書かれてあるのですが、何故必要なのか具体的な説明はないままです。

プログラムを見ても(あ)(い)が(main内で)使われている部分は無いですし、(あ)(い)の部分をコメントアウトして、コンパイルしても普通に実行されます。

この(あ)(い)は何故必要なのでしょうか。
回答の方宜しくお願いします。

###// ベクトルにクラスオブジェクトを保存する
###include <iostream>
###include <vector>
using namespace std;

class Demo {
double d;
public:
Demo() { d = 0.0; }
Demo(double x) { d = x; }
Demo &operator=(double x) {
d = x; return *this;
}
double getd() { return d; }
};

bool operator<(Demo a, Demo b) ・・・・・(あ)
{
return a.getd() < b.getd();
}

bool operator==(Demo a, Demo b) ・・・・・(い)
{
return a.getd() == b.getd();
}

int main()
{
vector<Demo> v;
int i;

for(i=0; i<10; i++)
v.push_back(Demo(i/3.0));

for(i=0; i<v.size(); i++)
cout << v[i].getd() << " ";

cout << endl;

for(i=0; i<v.size(); i++)
v[i] = v[i].getd() * 2.1;

for(i=0; i<v.size(); i++)
cout << v[i].getd() << " ";

cout << endl;

return 0;
}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ozwk

2020/05/29 06:28

参考書の話の流れでそのうち使うとかないですか?
iwanami

2020/05/29 07:56

参考書の内容は全部読み終えました。 この<vector>が最後の章に出てきているので、その章の中を探したのですが、これに関する説明はありませんでした。 今質問しておいてなんですが、もしかしたら本の主旨として「今は必要ないけど、将来的に必要になるから書いておこう」という感じだったのかと思いました。
guest

回答1

0

ベストアンサー

コード中に示した(あ)(い)の部分に関係演算子(<,==)のオーバーロードがされてあるんですが、
何故これが必要なのか分かりません。

たとえば、このvector<Demo> v; をソートしたくなって
std::sort(v.begin(), v.end()); と書いた途端、
関係演算子が定義されていないとコンパイルエラーです。

投稿2020/05/29 07:39

episteme

総合スコア16614

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

iwanami

2020/05/29 08:19

そうなんですか。 sort()の定義を確認できてないので分かりませんが、関係演算子のオーバーロードがある前提の定義をしているのでしょうか。 何故コンパイルエラーになるんでしょうか。 今<algorithm>ヘッダを付けて「sort(v.begin(),v.end());」をcoutの前に記述したら、コンパイルは出来ても実行すると 「terminate called after throwing an instance of 'std::bad_alloc' what(): std::bad_alloc」 とエラーが出ました。 僕の記述の仕方が間違っていたからかもしれませんが、(あ)(い)が記述されている状態でsort()したのですが、うまくいきませんでした。 これは何が原因なんでしょうか。
episteme

2020/05/29 08:22

> 何故コンパイルエラーになるんでしょうか。 比較できないものをどうやってソートするんです?
iwanami

2020/05/29 08:49

僕の返信の最初の4行だけに絞った回答でしょうか? 比較できないとは、「vector<Demo> v;がそもそも比較できるオブジェクトではない」のか、 「関係演算子がないと比較できない」、どちらの事を言っているのでしょうか
episteme

2020/05/29 10:32

> 僕の返信の最初の4行だけに絞った回答でしょうか? YES. > 比較できないとは、「vector<Demo> v;がそもそも比較できるオブジェクトではない」のか、 比較したいのは vector<Demo> ではなく Demo です。 >「関係演算子がないと比較できない」、どちらの事を言っているのでしょうか どっちが大きいか調べる手段がないと比較できません。 sort(v.begin(),v.end()); は その要素 Demo に対し operator< が定義されていることを 前提としています。(つまり a < b が定義されてなきゃエラー) 比較演算子を定義しないなら、 sort(v.begin(),v.end(), 2要素を比較する関数オブジェクト); のように、第3引数を与えることになります。
iwanami

2020/05/29 12:42

もう一度試してみたら、episteme さんが言っている通り、a<bのオーバーロードを定義していないと、 sort(v.begin(),v.end());と書くとエラーになりました。 a<bを定義すると実行できます。 sort(v.begin(),v.end(), 2要素を比較する関数オブジェクト);の2要素を比較する関数オブジェクトは想像つなかったので試せてないですが。 このコンテナと言われるオブジェクトに用いられる関数を使うには、関係(比較)演算子の定義が必要だという事が分かりました。 参考書が載せているので、意味のあるものだと思っていたのですが、その理由が具体的に知れて良かったです。
episteme

2020/05/29 13:08

> sort(v.begin(),v.end(), 2要素を比較する関数オブジェクト);の2要素を比較する > 関数オブジェクトは想像つなかったので試せてないですが。 sort(v.begin(), v.end(), [](Demo& a, Demo& b) { return a.getd() < b.getd();} );
iwanami

2020/05/30 04:57

わざわざコード記述してくださり、ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問