pair は STL のヘッダ <utility> で定義されている、二つの要素のペアを入れる入れ物です。
pair は二つの要素を入れる入れ物です。それぞれの要素は C++ のオブジェクトで、その型はテンプレート引数で決まります。簡単な例を見て見ましょう。この場合、int と float がテンプレート引数です。
#include <utility> using namespace std; int main() { pair<int, float> pairif; pairif.first = 1; pairif.second = 2.3f; }
pair は基本的には、次のように定義された struct PAIR に良く似ています。
struct PAIR { int first; float second; };
上記の構造体 PIAR と pair の差は、次のようなものです。
上記のような差があるのですが、pair は、ほぼ first と second をメンバ変数として持つ構造体であるわけです。
pair は二つの要素を入れるには便利なのですが、メンバ変数の名前が first と second に固定されているため、少し使いにくいところがあります。例えば、次の例を見てください。山の名前と、高さ/県名を結び付けようとしています。
#include <string> #include <utility> using namespace std; int main() { typedef pair<int, string> HEIGHTandPREFECTURE; // 高さと県名 pair<string, HEIGHTandPREFECTURE> mountname_height_pref; // 山の名前と属性 mountname_height_pref.first = "富士山"; mountname_height_pref.second.first = 3776 ; mountname_height_pref.second.second = "静岡" ; }
ナオ : 富士山は、静岡だけに属するのじゃないわよね。
店主 : まぁまぁ、そういう突っ込みは無しということで。
上記の例のように、メンバ名が first と second に固定されているので、.second.first などがこれを見ただけでは何を意味するのか分からないという問題があります。
これを逃れるためには、C++マニアック的には、クラスメンバへのポインタを使って、次のようにします。プレフィックス mp はメンバへのポインタの意味で使っています。
#include <string> #include <utility> using namespace std; int main() { // 変数型の typedef typedef pair<int, string> HEIGHTandPREFECTURE; typedef pair<string, HEIGHTandPREFECTURE> MOUNTNAME_ATTRIBUTE; // クラスメンバへのポインタの定義、ここは、料理で言えば仕込みの部分 string MOUNTNAME_ATTRIBUTE::* mpstrMountName = &MOUNTNAME_ATTRIBUTE::first ; HEIGHTandPREFECTURE MOUNTNAME_ATTRIBUTE::* mpAttribute = &MOUNTNAME_ATTRIBUTE::second; int HEIGHTandPREFECTURE::* mpiHeight = &HEIGHTandPREFECTURE::first ; string HEIGHTandPREFECTURE::* mpstrPrefecture = &HEIGHTandPREFECTURE::second; // オブジェクトの定義 MOUNTNAME_ATTRIBUTE mountname_attribute; // メンバ変ポインタを使ってメンバにアクセスする。 mountname_attribute.*mpstrMountName = "富士山"; mountname_attribute.*mpAttribute.*mpiHeight = 3776 ; mountname_attribute.*mpAttribute.*mpstrPrefecture = "静岡" ; }
ナオ : ちょっと丸秘テクって感じね。
店主 : いやぁ、それほどでも。