- ベストアンサー
enumの値から定義名を文字列化したい
C++でenumの値を元に、定義した名前(Fruits_Appleとか)を文字列として取得したいのですが、何か良い方法はないでしょうか? switch文等で分岐させて...という方法もありますが、enumの定義数が多くなるとコードが複雑になるので、シンプルな方法をさがしています。 enum Fruits{ Fruits_Apple, Fruits_Orange, Fruits_End }; void printFruits(Fruits fruits) { // ここで引数fruitsの値に応じて"Fruits_Apple"とか"Fruits_Orange"とかを // 文字列に代入したい std::string fruitsName = "Fruits_Apple"; }
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
こんばんは。 例えば、boostライブラリのメタプリプロセッサの如く、可視性など関係なしに手段を選ばなければナンボでも出来ます。 ただし一回でも陥ると地獄そのものです。 //------------------------------------------------------------------------------------- //misc.hpp //------------------------------------------------------------------------------------- #ifndef __MISC_HPP__ #define __MISC_HPP__ # define ArrayCount(a) (sizeof(a)/sizeof(a[0])) # define ArrayEnd(a) (a + ArrayCount(a)) #endif //------------------------------------------------------------------------------------- //misc.hpp //------------------------------------------------------------------------------------- //------------------------------------------------------------------------------------- //fruits.hpp //------------------------------------------------------------------------------------- #include"misc.hpp" //enumを作成する #ifdef MAKEENUM # define MAKEHDR(name) enum name { # define MAKELINE(name) name # define MAKEFTR(name) }; //arr##name##Pair[]を作成して、map##name##Resultに入れる #else # define MAKEHDR(name) std::pair<name, std::string> arr##name##Pair[] = { # define MAKELINE(name) std::make_pair(name, std::string(#name)) # define MAKEFTR(name) }; \ std::map<name, std::string> map##name##Result;\ {for(size_t n = 0; n < ArrayCount(arr##name##Pair); ++n)map##name##Result.insert(arr##name##Pair[n]);} #endif MAKEHDR(Fruits) MAKELINE(Fruits_Apple), MAKELINE(Fruits_Orange), MAKELINE(Fruits_End) MAKEFTR(Fruits) MAKEHDR(Gender) MAKELINE(Gender_Male), MAKELINE(Gender_Female), MAKELINE(Gender_End) MAKEFTR(Gender) #undef MAKEHDR #undef MAKELINE #undef MAKEFTR #undef MAKEENUM //------------------------------------------------------------------------------------- //fruits.hpp //------------------------------------------------------------------------------------- //------------------------------------------------------------------------------------- //test.cpp //------------------------------------------------------------------------------------- #include<map> #include<string> #include<iostream> //enumの作成 #define MAKEENUM #include"fruits.hpp" static void Print(Fruits fruits, Gender gender) { //map##name##Resultの作成 #include"fruits.hpp" std::cout << mapFruitsResult[fruits] << std::endl; std::cout << mapGenderResult[gender] << std::endl; } int main() { ::Print(Fruits_Apple, Gender_Female); return 0; } //------------------------------------------------------------------------------------- //test.cpp //-------------------------------------------------------------------------------------
その他の回答 (3)
- tsuduki123
- ベストアンサー率32% (21/65)
enum は コンパイルの時点で解決されることが多いので 地道にやるしかないですね。 要は名前に変換できればいいんですよね。 C++ならstd::mapを準備してあげるのが無難なのかなー? 僕なら、静的な配列と取得関数を作るけど。。。(C99) # 下はコンパイルしていないので文法ちょっと違うかも ----xxx.h enum Fruits { Fruits_Apple, Fruits_Orange, NumberOfFruits }; extern const char * getNameByFruits( const Fruits n ); ----xxx.c const char * getNameByFruitsIX( const Fruits n ) { static const char *FruitsName[NumberOfFruits] = { [Fruits_Apple] = "りんご", [Fruits_Orange] = "みかん", } if( n < NumberOfFruits ) return FruitsName[n]; return ""; }
- Tacosan
- ベストアンサー率23% (3656/15482)
マクロを駆使しつつ, map で変換関数でも書くかな. 例えば DeclareFruitMember(Apple) DeclareFruitMember(Orange) ... #undef DeclareFruitMember と書かれたファイルを作って, enum Fruits { #define DeclareFruitMember(mem) Fruits_##mem, #include "それ" }; std::pair<enum Fruits, std::string> fruitMemberStrings[] = { #define DeclareFruitMember(mem) { Fruits_##mem, "Fruits_" #mem }, #include "それ" }; std::map<enum Fruits, std::string> fruitMemberMap(fruitsMemberStrings, fruitsMemberStrings+要素数); みたいに.
- MrBan
- ベストアンサー率53% (331/615)
マクロ(define)からならこんなことはできますけど… #define APPLE 0 #define TO_STR(str) #str TO_STR(APPLE) 残念ながらenumからはないんじゃないですかね。(あれば知りたい) # 無理矢理派生クラスで独自enum風クラスを作って、 # typeid().name()をつかって…とか考えると、 # 素直に変換関数を書いた方がよほどシンプルだと思いますし。 # もしくは、(独自)プリプロセッサをかませるか。