環境
VisualStudio2012
Windows7
やりたいこと
複数の要素からなるキーに応じて何かの値を持ちたい。
struct KeyData
{
std::string name;
int score;
};
std::map<KeyData, std::string> mp;
mp[getKeyData(0)] = "abcde";
mp[getKeyData(1)] = "qwert";
やり方
簡単に言えば、キーとなるクラスや構造体に operator< を定義すればよいだけ。
コード
# include <iostream>
# include <string>
# include <map>
# include <locale>
# include <clocale>
# include <tuple>
namespace
{
//! キーとなる構造体
struct KeyData
{
//! 名前
std::wstring name;
//! ID
int id;
//! コンストラクタ
KeyData()
: name()
, id(0)
{
}
//! コンストラクタ
KeyData
(
const std::wstring& name_,
const int id_
)
: name(name_)
, id(id_)
{
}
//! 比較演算子
bool operator<(const KeyData& value) const
{
# if 1
//! @note コメントでの指摘反映。
return std::tie(name, id) < std::tie(value.name, value.id);
# else
if (name < value.name)
{
return true;
}
if (name == value.name)
{
if (id < value.id)
{
return true;
}
}
return false;
# endif
}
};
//! KeyDataをキーにしたマップ
typedef std::map<KeyData, int> KeyDataMap;
} // namespace
int main()
{
std::locale::global(std::locale("japanese"));
std::setlocale(LC_ALL, "japanese");
KeyDataMap mp;
mp[KeyData(L"人間", 0)] = 0;
mp[KeyData(L"モスラ", 0)] = 1;
mp[KeyData(L"モスラ", 1)] = 11;
mp[KeyData(L"人間", 2)] = 22;
mp[KeyData(L"モスラ", 3)] = 33;
mp[KeyData(L"ゴジラ", 4)] = 44;
// 上書き
mp[KeyData(L"ゴジラ", 4)] = 9999;
for (auto const &v : mp)
{
const auto &key = v.first;
std::wcout << L"[" << key.name << L"]"
<< L"(" << key.id << L")"
<< L":" << v.second << std::endl;
}
return 0;
}
参考
C++ の STD::MAP のキーに構造体を使う方法と、ハマったこと
setやmapのキーに任意のクラスを渡す
優先順位付き大小比較