std::greaterとstd::lessの挙動がよくわからん
あるクラスのオブジェクトが入ったコンテナを、そのクラスのメンバーの大小に応じて、ソートしたい、そんな時、あると思います。
だけど、書き方がよくわからんかったのでメモ。クラスの外に比較用のプレディケェード作れば楽ってのは知ってるのだが、こうしたかった。
この辺の「sort比較演算子は < がデフォで > の時にはなんかある」みたいな話はどこかのC++本 or サイトで見た記憶があるのだが全く思い出せない…
そして、以下のコードはVS2013だと通るんだけど、ideoneのgcc(4.8.1)で試したらアウトだった。ぐぬぬ。
#include<iostream> #include<vector> #include <functional> #include<algorithm> //適当なクラス struct Hoge { Hoge(int x) : x_(x){} bool operator<(const Hoge & inRhs){ return x_ < inRhs.x_; } bool operator>(const Hoge & inRhs){ return !(this->operator<(inRhs.x_)); } int x_; }; int main() { //適当なデータ std::vector<Hoge> hoges; hoges.push_back(Hoge(9)); hoges.push_back(Hoge(1)); hoges.push_back(Hoge(3)); hoges.push_back(Hoge(7)); hoges.push_back(Hoge(4)); std::cout << "元のデータ" << std::endl; std::for_each(hoges.begin(), hoges.end(), [](Hoge & hoge){std::cout << hoge.x_ << std::endl; }); //↓はだめ //std::sort(hoges.begin(), hoges.end(), std::less<Hoge>()); //↓はいい //std::sort(hoges.begin(), hoges.end(), std::less<>()); //↓はいい //std::sort(hoges.begin(), hoges.end(), std::less<Hoge&>()); std::sort(hoges.begin(), hoges.end()); std::cout << "x_の昇順にソートしたデータ" << std::endl; std::for_each(hoges.begin(), hoges.end(), [](Hoge & hoge){std::cout << hoge.x_ << std::endl; }); //↓はだめ //std::sort(hoges.begin(), hoges.end(), std::greater<Hoge>()); //↓はいい //std::sort(hoges.begin(), hoges.end(), std::greater<Hoge&>()); std::sort(hoges.begin(), hoges.end(), std::greater<>()); std::cout << "x_の降順にソートしたデータ" << std::endl; std::for_each(hoges.begin(), hoges.end(), [](Hoge & hoge){std::cout << hoge.x_ << std::endl; }); return 0; }
実行結果。
元のデータ 9 1 3 7 4 x_の昇順にソートしたデータ 1 3 4 7 9 x_の降順にソートしたデータ 9 7 4 3 1
〜2014/01/31追記〜
コメント欄でアドバイスいただいたように、constメソッドになってないからだった。↓にすれば全部のコードでOKだった。
ありがとうございます!
struct Hoge { Hoge(int x) : x_(x){} bool operator<(const Hoge & inRhs) const{ return x_ < inRhs.x_; } bool operator>(const Hoge & inRhs) const{ return !(this->operator<(inRhs.x_)); } int x_; };