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

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

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

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

Q&A

解決済

2回答

732閲覧

ポインタの配列をソートしたい

YUKI_DAYO

総合スコア19

C++

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

0グッド

2クリップ

投稿2022/07/06 10:55

こんにちは。

C++

1#include <bits/stdc++.h> 2 3 4class MyClass { 5private: 6 int x; 7 8public: 9 MyClass(int _x) 10 : x(_x) { } 11 12 int getX() const { 13 return x; 14 } 15 16 void print() const { 17 std::cout << x << std::endl; 18 } 19}; 20 21bool operator < (const MyClass & a, const MyClass & b) { 22 return a.getX() < b.getX(); 23} 24 25int main() { 26 std::vector<MyClass *> hoge = { 27 new MyClass(56), new MyClass(32), new MyClass(143), new MyClass(14), 28 }; 29 30 std::sort(hoge.begin(), hoge.end()); 31 32 for (const auto h : hoge) { 33 h->print(); 34 } 35 36 for (auto h : hoge) { 37 delete h; 38 } 39}

タイトル通り、以上のようなコードでポインタの配列をソートしたいです。上記のコードをそのまま実行すると std::sort はアドレスでソートするので、ソート後の hoge の要素順は未定義かと思います。

これを正しく(14, 32, 56, 143)となるようにソートしたいです。

現状私が知っている方法は

  • std::function やラムダ式、関数オブジェクト等を使用して引数がポインタとなっているもの(bool comp(const MyClass * a, const MyClass * b))を第3引数の Compare comp にぶち込む。

なのですが、どれも新たな関数、構造体等を作成しなければならず、コードを複雑化させる要因になります。できれば operator <だけを利用して、新たな関数、構造体等を作成せずにソートしたいです。

何か方法をご存じでしたら教えてください。お願いします。

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

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

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

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

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

guest

回答2

0

比較関数を std::sort に与える:

C++

1#include <iostream> 2#include <vector> 3#include <algorithm> 4 5class MyClass { 6private: 7 int x; 8 9public: 10 MyClass(int _x) : x(_x) { } 11 int getX() const { return x; } 12 void print() const { std::cout << x << std::endl; } 13}; 14 15int main() { 16 std::vector<MyClass *> hoge = { 17 new MyClass(56), new MyClass(32), new MyClass(143), new MyClass(14), 18 }; 19 20 std::sort(hoge.begin(), hoge.end(), [](MyClass* px, MyClass* py) { return px->getX() < py->getX(); }); 21 22 for (const auto h : hoge) { 23 h->print(); 24 } 25 26 for (auto h : hoge) { 27 delete h; 28 } 29}

投稿2022/07/06 11:58

episteme

総合スコア16614

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

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

YUKI_DAYO

2022/07/06 14:22 編集

回答ありがとうございます。 書いている通り、 > できれば operator <だけを利用して、**新たな関数、構造体等を作成せずに**ソートしたいです。 のです。 複数個所でソートしたいので、ラムダ式はできれば使いたくないのです。 ほかに方法をご存じでしたら教えていただけるとありがたいです。
maisumakun

2022/07/07 00:04

> 複数個所でソートしたいので、ラムダ式はできれば使いたくないのです。 複数箇所で使うのであれば、なおのこと比較用の構造を定常的に持っておいたほうが便利かと思うのですが、それは何が問題なのでしょうか。
episteme

2022/07/07 01:47

↑せやね。 template <typename T> struct ptr_less { bool operator()(const T* px, const T* py) const { return *px < *py; } }; を定義しておいて: std::sort(hoge.begin(), hoge.end(), ptr_less<MyClass>());
YUKI_DAYO

2022/07/17 13:29

10日も放置してしまって申し訳ありません。 私が望んでいたのは、"新たな構造体等を作成せずに"ということでした。 @maisumakun さんと @episteme さんの仰ることはごもっともなのですが、スコープが汚れるのと、若干意地のようなものが混じっていたようです。 現在は関数オブジェクトで実装しましたので結局 @episteme さんの方法になりました。 回答ありがとうございました!返信遅れてすみません!
guest

0

ベストアンサー

std::vector<MyClass *>をstd::vector<std::shared_ptr<MyClass>>とかにするのはどう?
nullとの比較問題があるからポインタ系が実態比較をするはずがないですね、、、
vector<referece_wrapper<MyClass>>かなあ。

投稿2022/07/06 11:48

編集2022/07/06 14:53
matukeso

総合スコア1590

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

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

YUKI_DAYO

2022/07/06 14:29

回答ありがとうございます。 std::vector<MyClass *> を std::vector<std::shared_ptr<MyClass>> に変更し実行してみましたが、どうやら同じくアドレス値でソートされるようです。 ほかに方法をご存じでしたら教えていただけるとありがたいです。
YUKI_DAYO

2022/07/06 15:13

なるほど、(実際のコードでも nullptr が入っていることはないので)nullptr のことは考えていませんでした。 確かにその通りですね。ラッパー作るとそれはそれでまた複雑化するので関数オブジェクトで実装しようと思います。 ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問