ファンクタ(functor、関数オブジェクト)を使ってvectorに入れたオブジェクトをメンバーでソートする方法の紹介です。
ファンクタ(functor、関数オブジェクト)の使い方
C++のSTL(標準テンプレートライブラリ、Standard Template Library)でvectorにオブジェクトを入れておいてオブジェクトのメンバーによってソートしたいということがあります。
こういう時に使うのに便利なのがC++のファンクタ(functor)と呼ばれる機能です。
関数オブジェクトとも呼ばれます。
説明するよりもこの種の使い方はサンプルを見てもらうとよくわかると思いますのでサンプルコードと実行結果を載せてみました。
①静的関数(static function)を使う方法
②ファンクタ(functor)を使う方法
の2種類を載せてあります。
std::sortの使い方も合わせて見てみてください。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
#include "stdafx.h" #include <iostream> #include <vector> #include <algorithm> #include <functional> #include <sstream> #include <string> using namespace std; class VectorTest { public: //①静的関数でソートする static bool compare1(VectorTest vt1, VectorTest vt2) { return (vt1.number < vt2.number); } //②ファンクタでソートする struct compare2 : public binary_function<VectorTest, VectorTest, bool> { bool operator()( VectorTest vt1, VectorTest vt2) { return (vt1.number < vt2.number); } }; int number; string str; }; int main() { vector<VectorTest> vectorTest; VectorTest data; stringstream ss; for(unsigned int i = 0; i < 5; ++i) { data.number = i; ss << data.number; data.str = ss.str(); vectorTest.push_back(data); } // ①静的関数でソートする std::random_shuffle(vectorTest.begin(), vectorTest.end()); std::sort(vectorTest.begin(), vectorTest.end(), VectorTest::compare1); //compare1には()がない cout << "static function result" << endl; for (vector<VectorTest>::const_iterator citer = vectorTest.begin(); citer != vectorTest.end(); ++citer) { cout << (*citer).number << " " << (*citer).str << endl; } // ②ファンクタでソートする場合 std::random_shuffle(vectorTest.begin(), vectorTest.end()); std::sort(vectorTest.begin(), vectorTest.end(), VectorTest::compare2()); //compare2には()がある cout << endl; cout << "functo test result" << endl; for (vector<VectorTest>::const_iterator citer = vectorTest.begin(); citer != vectorTest.end(); ++citer) { cout << (*citer).number << " " << (*citer).str << endl; } return 1; } |
実行結果は以下の通りです。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
static function result 0 0 1 01 2 012 3 0123 4 01234 functo test result 0 0 1 01 2 012 3 0123 4 01234 |
今回は静的関数、ファンクタ(functor)のどちらを使っても、vectorに含まれるオブジェクトをメンバによってソートすることが可能です。
ただし、ファンクタを使うようにした方がのちのち応用が利くようになるし、プログラムがよりエレガントに見えます。
そういう意味で、特にC++でこの種のコードを書くときはファンクタを使うようにしましょう。
Error :namespace “std” にメンバー”sort”がありません
ところで、こんなエラーメッセージが表示されることがあります。
Error :namespace “std” にメンバー”sort”がありません
#include <algorithm>が必要です。
std::sortは慣れてくるととても便利です。
プログラミングの無料レッスン体験
約8,000名の受講生と80社以上の導入実績のあるプログラミングやWebデザインのオンラインマンツーマンレッスンCodecamp
<Codecampの特徴>
1 現役エンジニアによる指導
2オンラインでのマンツーマン形式の講義
3大手企業にも導入されている実践的なカリキュラム
↓無料体験レッスン実施中です。
コメント