C++で連想配列の値を動的型に
この記事は最終更新日から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

以上です。


芽萌丸プログラミング部
芽萌丸プログラミング部@programming
プログラミング関連アカウント。Web標準技術を中心に書いていきます。フロントエンドからサーバサイドまで JavaScript だけで済ませたい人たちの集いです。記事は主に @TanakaSoftwareLab が担当。