【C++】enumと文字列を相互変換したい

enumの列挙定数名から文字列を取得したいと思った人は少なからずいると思う。そこで、色々試してみた。
 

マクロを使う

#define STR(var) #var

これを使うと、変数名がそのまま文字列として変換される。そう、変数名がである。つまり、代入されている列挙定数名を文字列としてあることはできない。
 

連想配列を使う

てことで第二の方法として、unordered_mapを使用して列挙定数と文字列を対応させる。そんなことをするなら最初からunordered_mapを使えとは言っちゃいけない。enumも必要な場面なんだよ。

enum color{
   RED,
   GREEN,
   BLUE
 }; 

こんなような列挙体があるとする
それを、unordered_mapで保持しようとすると以下のような感じになる。

std::unordered_map map;

ここに、対応表を作っていくことになる。

map[color::RED] = "RED";

とすれば良い。
値の取り出しはat()を使えば良いので以下のようになる。

map.at(color::RED);

一般化してみた

連想配列を使った方法を一般化してみた。どうせなので文字列から列挙定数を返せるようにもしてみた。

#include 
#include 
#include 
#include 
enum color{
  RED,
  BLUE,
  GREEN,
  WHITE,
  BLACK
};
template 
class enumStr{
  public:
    explicit enumStr(){}
    enumStr(const enumStr&) = delete;
    /// @brief enumのmapにkeyと文字列を追加する
    /// @param _key enumの列挙定数
    /// @param _str 連想したい文字列
    /// @return none
    void addKey(Key _key, std::string _str){
      // 指定した列挙定数が登録されていなければ登録する
      if(e2s.count(_key) == 0) e2s[_key] = _str;
      if(s2e.count(_str) == 0) s2e[_str] = _key;
    }
    /// @brief enumのmaoにkeyと文字列を複数登録する
    /// @param _pairs 列挙定数と連想文字列をペアにしたもの
    /// @return none
    void addKeys(std::vector> _pairs){
      for(auto pair : _pairs){
        addKey(pair.first, pair.second);
      }
    }
    /// @brief 列挙定数を元に文字列を返すやつ
    /// @param _key 列挙定数
    /// @return 対応した文字列
    std::string operator()(Key _key){
      // 指定した列挙定数が登録されていればその文字列を返す
      if(e2s.count(_key) != 0) return e2s.at(_key);
      return "";
    }
    /// @brief 文字列を元に列挙定数を返すやつ
    /// @param _str 列挙定数を表す文字列
    /// @return 列挙定数, 登録されていなければ`0`
    Key operator()(std::string _str){
      if(s2e.count(_str) != 0) return s2e.at(_str);
      return static_cast(0);
    }
  private:
    std::unordered_map e2s;
    std::unordered_map s2e;
};
int main(){
  enumStr sample;
  // keyを一つだけ追加する
  sample.addKey(color::RED, "RED");
  // keyを複数個登録する
  sample.addKeys({
        {color::BLUE, "BLUE"},
        {color::GREEN, "GREEN"},
        {color::WHITE, "WHITE"},
        {color::BLACK, "BLACK"}
      });
  // keyを元に文字列を取り出す
  std::cout << sample(color::RED) << std::endl;
  std::cout << sample(color::BLACK) << std::endl;
  std::cout << sample("GREEN") << std::endl;
}

おすすめ

1件の返信

  1. google より:

    I like the valuable information you provide in your articles.
    I’ll bookmark your weblog and check again here frequently.
    I am quite certain I’ll learn many new stuff right
    here! Good luck for the next! http://pokerhp.net/

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です