コンテナがクラスのpriority_queue
優先度キューに抱いていた勝手な幻想
STLのpriority_queue、つまり優先度キューのお話です。
priority_queue - C++ Reference
今作っているアプリケーションで、priority_queueのコンテナをクラスにして、それらを優先度順にプッシュできれば、いい感じに作れそうなモジュールがあります。priority_queueは使ったことがないのですが、何となく以下のような感じでいけると思っていました。勝手な幻想を抱いていたものです。
// 優先度キューで管理するコンテナ class TContainer { public: // コンストラクター TContainer(string message) : m_Message(message) {} // メッセージを返すアクセサメソッド string getMessage() { return m_Message; } private: const string m_Message; } // メイン void main() { priority_queue<TContainer> priorityQueue; // 中・低・高の順でプッシュするけど第二引数で優先度を指定する。 priorityQueue.push(TContainer("優先度:中"), 2); priorityQueue.push(TContainer("優先度:低"), 1); priorityQueue.push(TContainer("優先度:高"), 3); // すると、高・中・低の順に並び変わっている、という勝手な幻想。 while (!priorityQueue.empty()) { cout << priorityQueue.top().getMessage() << endl; priorityQueue.pop(); } }
現実
まあ、結論から言うと、こんなことはできないのです。私の手元の入門書籍や、WEBサイトを見て回ったところ、int型のコンテナを管理するqueueがに、そのint型の値順にソートするサンプルしか見つからないのです。こんな感じです。
void main() { priority_queue<int> priorityQueue; priorityQueue.push(2); priorityQueue.push(1); priorityQueue.push(3); while (!priorityQueue.empty()) { cout << priorityQueue.top() << endl; priorityQueue.pop(); } }
対策コード
こんなの俺が思っている優先度キューじゃない!ということで、自分で無理矢理やることにしました。とりあえず完成したコードを見てください。
#include <iostream> #include <queue> #include <string> using namespace std; // 優先度キューで管理するコンテナ class TContainer { public: // コンストラクター TContainer(string message, unsigned int priority) : m_Message(message), m_Priority(priority) {} // 比較演算子のオーバーロード bool operator < (const TContainer &container) const { return (m_Priority < container.m_Priority); } // メッセージを返すアクセサメソッド string getMessage() { return m_Message; } private: // メッセージ const string m_Message; // 優先度(数値が大きいほど高い) const unsigned int m_Priority; }; // メイン void main() { priority_queue<TContainer, vector<TContainer>, less<TContainer> > priorityQueue; // 中・低・高の順でプッシュするけど priorityQueue.push(TContainer("優先度:中", 2)); priorityQueue.push(TContainer("優先度:低", 1)); priorityQueue.push(TContainer("優先度:高", 3)); // 高・中・低の順に並び変わっているのだ。 while (!priorityQueue.empty()) { cout << priorityQueue.top().getMessage() << endl; priorityQueue.pop(); } }
説明
要はソートの条件があれば良いわけです。まず、コンテナのクラスに優先度のメンバーを作ります。メンバーはコンストラクターで与えられます。
private: // 優先度(数値が大きいほど高い) unsigned int m_Priority;
そして、ソートするために比較演算子をオーバーロードします。
// 比較演算子のオーバーロード bool operator < (const TContainer &container) const { return (m_Priority < container.m_Priority); }
これだけです。簡単ですね。あとは、プッシュする時はこんな感じです。
priorityQueue.push(TContainer("優先度:中", 2));
という感じで、めでたく幻想を現実にすることができました。少しC++らしいことが自力でできて嬉しいです。
ではでは。