この記事は最終更新日から1年以上が経過しています。
@programming
投稿日 2021/2/5
更新日 2021/2/5 ✏
C++で連想配列の値を動的型に
C++での連想配列は標準ライブラリのstd::map
で取り扱うことができますが、今回は連想配列の値部分にどんな型でも入れられるよう動的型にしたいと思います。 動的型にはstd::any
を使いますので、あらかじめC++17を使えるようにしておく必要があります。
目次:
前提
- Ubuntu 16.04 LTS
- g++ 7.5.0 (C++17対応)
サンプルコード
map-test.cpp
#include <iostream>
#include <map>
#include <any>
using namespace std;
int main(int argc, char* argv[]) {
// keyはstring, valueは動的型のanyで連想配列を定義:
map<string, any> myMap;
// 連想配列に Key & Value をセット:
myMap["aaa"] = string("あいうえお");
myMap["bbb"] = string("かきくけこ");
myMap["ccc"] = 123;
myMap["ddd"] = 999.999;
// 連想配列からキー"aaa"の値のコピーを取得:
auto aaa = any_cast<string>(myMap["aaa"]);
cout << "\naaaのvalueのコピー:" << endl;
cout << aaa << endl;
// 連想配列からキー"aaa"の参照を取得:
string& aaap = any_cast<string&>(myMap["aaa"]);
cout << "\naaaのvalueの参照:" << endl;
cout << aaap << endl; // "あいうえお"
// 参照を更新してみる:
aaap = string("アイウエオ");
cout << "\naaaの参照を更新:" << endl;
cout << aaap << endl; // "アイウエオ"
cout << "\nアイテム数(1件削除前): " << myMap.size() << endl;
// 連想配列からキー"bbb"を削除:
myMap.erase("bbb");
cout << "\nアイテム数(1件削除後): " << myMap.size() << endl;
// 全てのkey&valueをダンプ:
cout << "\n全てのkey&valueをダンプ:" << endl;
for (auto it = myMap.cbegin(); it != myMap.cend(); ++it) {
auto k = it->first; // keyを取得
auto v = it->second; // valueの値を取得
string type = v.type().name(); // valueの型名を取得
// 型名ごとに出力内容を切り分け:
if (type == "i") {
// ** 型名が "i" (int型) の場合:
cout << k << ": " << any_cast<int>(v) << " (int)" << endl;
} else if (type == "d") {
// ** 型名が "d" (double型) の場合:
cout << k << ": " << any_cast<double>(v) << " (double)" << endl;
} else {
// ** それ以外はとりあえずstring型と見做しておく:
cout << k << ": " << any_cast<string>(v) << " (string)" << endl;
}
}
// 全てのkey&valueを削除:
myMap.clear();
cout << "\n全件削除後のアイテム数: " << myMap.size() << endl;
}
コンパイル&実行
## コンパイル&実行 (-std=c++17オプションを付けてC++17対応)
$ g++ -o a.out map-test.cpp -std=c++17 && ./a.out
aaaのvalueのコピー:
あいうえお
aaaのvalueの参照:
あいうえお
aaaの参照を更新:
アイウエオ
アイテム数(1件削除前): 4
アイテム数(1件削除後): 3
全てのkey&valueをダンプ:
aaa: アイウエオ (string)
ccc: 123 (int)
ddd: 999.999 (double)
全件削除後のアイテム数: 0
以上です。