Misalkan kita memiliki beberapa enum bernama:
enum MyEnum {
FOO,
BAR = 0x50
};
Yang saya cari di Google adalah skrip (bahasa apa saja) yang memindai semua header dalam proyek saya dan menghasilkan header dengan satu fungsi per enum.
char* enum_to_string(MyEnum t);
Dan implementasi dengan sesuatu seperti ini:
char* enum_to_string(MyEnum t){
switch(t){
case FOO:
return "FOO";
case BAR:
return "BAR";
default:
return "INVALID ENUM";
}
}
Gotcha benar-benar dengan enum jenis huruf, dan enum gaya C tanpa nama. Apakah ada yang tahu sesuatu tentang ini?
EDIT: Solusinya tidak boleh mengubah sumber saya, kecuali untuk fungsi yang dihasilkan. Enum berada dalam API, jadi menggunakan solusi yang diusulkan sampai sekarang bukanlah pilihan.
Jawaban:
Anda mungkin ingin melihat GCCXML .
Menjalankan GCCXML pada kode sampel Anda menghasilkan:
Anda dapat menggunakan bahasa apa pun yang Anda inginkan untuk mengeluarkan tag Enumeration dan EnumValue dan menghasilkan kode yang Anda inginkan.
sumber
X-macro adalah solusi terbaik. Contoh:
colours.def:
Namun, saya biasanya lebih suka metode berikut, sehingga mungkin untuk sedikit mengubah string.
sumber
#define X(a, b) #b
. Ini hanya diperlukan jika definisi terlihat seperti iniX(Red, red)
, daripada definisi yang ditunjukkan dalam jawaban,X(Red, "red")
@hydroo: Tanpa file tambahan:
sumber
MetaSyntacticVariableNames[]
menjadi bagian dari deklarasi kelas, dengan membuat metodestatic const char* getNameByEnum(MetaSyntacticVariable e) { /*code to return the static string*/ }
Yang cenderung saya lakukan adalah membuat array C dengan nama dalam urutan dan posisi yang sama dengan nilai enum.
misalnya.
maka Anda dapat menggunakan larik di tempat-tempat yang Anda inginkan nilai yang dapat dibaca manusia, mis
Anda dapat bereksperimen sedikit dengan operator merangkai (lihat # dalam referensi praprosesor Anda) yang akan melakukan apa yang Anda inginkan, dalam beberapa keadaan- misalnya:
akan mencetak "merah" ke stdout. Sayangnya itu tidak akan berfungsi untuk variabel (karena Anda akan mendapatkan nama variabel yang dicetak)
sumber
Saya memiliki makro yang sangat mudah digunakan yang melakukan ini dengan cara yang benar-benar KERING. Ini melibatkan makro variadic dan beberapa keajaiban parsing sederhana. Ini dia:
Untuk menggunakan ini di kode Anda, cukup lakukan:
sumber
QT mampu menarik itu (berkat kompiler objek meta):
Sumber
sumber
Ini dapat dilakukan di C ++ 11
sumber
Saya baru saja menemukan kembali roda ini hari ini, dan berpikir saya akan membagikannya.
Implementasi ini tidak memerlukan perubahan apa pun pada kode yang mendefinisikan konstanta, yang dapat berupa enumerasi atau
#define
s atau apa pun yang berpindah ke integer - dalam kasus saya, saya memiliki simbol yang ditentukan dalam istilah simbol lain. Ini juga bekerja dengan baik dengan nilai yang jarang. Ia bahkan memungkinkan banyak nama untuk nilai yang sama, selalu mengembalikan yang pertama. Satu-satunya downside adalah bahwa Anda harus membuat tabel konstanta, yang mungkin sudah ketinggalan zaman karena yang baru ditambahkan misalnya.Contoh bagaimana Anda akan menggunakannya:
The
IdToName
fungsi bergantung padastd::lower_bound
untuk melakukan pencarian cepat, yang mengharuskan tabel yang akan diurutkan. Jika dua entri pertama dalam tabel rusak, fungsi akan mengurutkannya secara otomatis.Sunting: Sebuah komentar membuat saya memikirkan cara lain untuk menggunakan prinsip yang sama. Makro menyederhanakan pembuatan
switch
pernyataan besar .sumber
switch and case
karena sederhana dan mudah dimengerti.Pembahasan lebih lanjut tentang metode ini
Trik direktif preprocessor untuk pendatang baru
sumber
Menarik untuk melihat banyak cara. inilah yang saya gunakan sejak lama:
di file myenummap.h:
di main.cpp
Ini bukan const, tapi nyaman.
Berikut cara lain yang menggunakan fitur C ++ 11. Ini adalah const, tidak mewarisi container STL dan sedikit lebih rapi:
sumber
Pemakaian:
sumber
MyEnum x = MyEnum::TWO;
. Saya telah memposting hasil edit saya tentang kelas Anda untuk mendukung ini.Solusi makro Suma bagus. Anda tidak perlu memiliki dua makro yang berbeda. C ++ akan dengan senang hati menyertakan header dua kali. Tinggalkan saja include guardnya.
Jadi Anda akan memiliki foobar.h yang mendefinisikan adil
dan Anda akan memasukkannya seperti ini:
enumfactory.h akan melakukan 2
#include ENUMFACTORY_ARGUMENT
detik. Di babak pertama, ENUM diperluas seperti milik SumaDECLARE_ENUM
; di babak kedua ENUM bekerja sepertiDEFINE_ENUM
.Anda juga dapat menyertakan enumfactory.h beberapa kali, selama Anda meneruskan # define yang berbeda untuk ENUMFACTORY_ARGUMENT
sumber
Perhatikan bahwa fungsi konversi Anda idealnya mengembalikan karakter const *.
Jika Anda mampu untuk menempatkan enum Anda di file header terpisah, Anda mungkin bisa melakukan sesuatu seperti ini dengan makro (oh, ini akan jelek):
Di mana enum_def.h memiliki:
Dan enum_conv.h memiliki:
Dan terakhir, colour.h memiliki:
Dan Anda dapat menggunakan fungsi konversi sebagai:
Ini jelek, tapi itu satu-satunya cara (di tingkat preprocessor) yang memungkinkan Anda menentukan enum Anda hanya di satu tempat dalam kode Anda. Oleh karena itu, kode Anda tidak rentan terhadap kesalahan karena modifikasi pada enum. Definisi enum Anda dan fungsi konversi akan selalu sinkron. Namun, saya ulangi, ini jelek :)
sumber
Jawaban lain: dalam beberapa konteks, masuk akal untuk mendefinisikan enumerasi Anda dalam format non-kode, seperti file CSV, YAML, atau XML, dan kemudian menghasilkan kode enumerasi C ++ dan kode to-string dari definisi tersebut. Pendekatan ini mungkin atau mungkin tidak praktis dalam aplikasi Anda, tetapi itu adalah sesuatu yang perlu diingat.
sumber
Ini adalah modifikasi dari jawaban @ user3360260. Ini memiliki beberapa fitur baru berikut
MyEnum fromString(const string&)
dukungPemakaian:
Ini kodenya
Perhatikan bahwa konversi keString adalah pencarian cepat, sedangkan konversi fromString adalah pencarian linier yang lambat. Namun string sangat mahal (dan file IO terkait), saya tidak merasa perlu untuk mengoptimalkan atau menggunakan bimap.
sumber
Berikut solusi satu file (berdasarkan jawaban elegan oleh @Marcin:
sumber
Saya melakukan ini dengan kelas pembungkus enum side-by-side terpisah yang dihasilkan dengan makro. Ada beberapa keuntungan:
Kelemahannya, tentu saja, adalah saya perlu menduplikasi nilai enum di kelas pemformat, dan saya tidak memiliki skrip untuk membuatnya. Selain itu, tampaknya bekerja dengan cukup baik.
Berikut adalah contoh enum dari basis kode saya, tanpa semua kode kerangka kerja yang mengimplementasikan makro dan templat, tetapi Anda bisa mendapatkan idenya:
Idenya adalah alih-alih menggunakan EHelpLocation, Anda menggunakan SEHelpLocation; semuanya bekerja sama, tetapi Anda mendapatkan pemeriksaan rentang dan metode 'Format ()' pada variabel enum itu sendiri. Jika Anda perlu memformat nilai yang berdiri sendiri, Anda dapat menggunakan CEnumFormatter_EHelpLocation :: FormatEnum (...).
Semoga bermanfaat. Saya menyadari ini juga tidak menjawab pertanyaan asli tentang skrip untuk benar-benar menghasilkan kelas lain, tetapi saya harap strukturnya membantu seseorang mencoba memecahkan masalah yang sama, atau menulis skrip semacam itu.
sumber
Ini adalah perangkat lunak yang belum dirilis tetapi tampaknya BOOST_ENUM dari Frank Laub sesuai dengan tagihan. Bagian yang saya sukai adalah Anda dapat mendefinisikan enum dalam lingkup kelas yang biasanya tidak diizinkan oleh sebagian besar enum berbasis Makro. Itu terletak di Boost Vault di: http://www.boostpro.com/vault/index.php?action=downloadfile&filename=enum_rev4.6.zip&directory=& Belum melihat perkembangan apa pun sejak tahun 2006 jadi saya tidak tahu seberapa baik kompilasi dengan rilis Boost baru. Lihat di bawah libs / test untuk contoh penggunaan.
sumber
Ini adalah solusi saya dengan BOOST:
Untuk membuat enum, nyatakan:
Untuk konversi:
sumber
Saya ingin memposting ini jika ada yang menganggapnya berguna.
Dalam kasus saya, saya hanya perlu membuat
ToString()
danFromString()
berfungsi untuk satu enum C ++ 11 dari satu.hpp
file.Saya menulis skrip python yang mem-parsing file header yang berisi item enum dan menghasilkan fungsi dalam
.cpp
file baru .Anda dapat menambahkan skrip ini di CMakeLists.txt dengan execute_process , atau sebagai acara pra-bangun di Visual Studio. The
.cpp
file akan secara otomatis dihasilkan, tanpa perlu update secara manual setiap kali item enum baru ditambahkan.generate_enum_strings.py
Contoh:
ErrorCode.hpp
Lari
python generate_enum_strings.py ErrorCode.hpp
Hasil:
ErrorCode.cpp
sumber
Menambahkan lebih banyak kesederhanaan penggunaan ke jawaban fantastis Jasper Bekkers :
Siapkan sekali:
Kemudian, untuk pemakaian:
sumber
Anda bisa menggunakan perpustakaan refleksi, seperti Merenungkan . Anda mendaftarkan enum dan kemudian Anda dapat mengubahnya bolak-balik dengan API.
sumber
Masalah dengan jawaban 0 adalah bahwa nilai biner enum tidak selalu dimulai dari 0 dan tidak harus bersebelahan.
Ketika saya membutuhkan ini, saya biasanya:
sumber
Skrip ruby berikut mencoba mengurai header dan membangun sumber yang diperlukan di samping header asli.
Menggunakan ekspresi reguler membuat "parser" ini cukup rapuh, mungkin tidak dapat menangani header spesifik Anda dengan baik.
Misalkan Anda memiliki header toto / ah, yang berisi definisi untuk enum MyEnum dan MyEnum2. Skrip akan membangun:
Solusi yang lebih kuat adalah:
sumber
Itu adalah satu-satunya cara yang bisa dilakukan (array string juga bisa berfungsi).
Masalahnya adalah, setelah program C dikompilasi, nilai biner dari enum adalah semua yang digunakan, dan namanya hilang.
sumber
Berikut adalah program CLI yang saya tulis untuk dengan mudah mengubah enum menjadi string. Mudah digunakan, dan membutuhkan waktu sekitar 5 detik untuk menyelesaikannya (termasuk waktu untuk melakukan cd ke direktori yang berisi program, lalu menjalankannya, meneruskan file yang berisi enum ke sana).
Unduh di sini: http://www.mediafire.com/?nttignoozzz
Topik diskusi di sini: http://cboard.cprogramming.com/projects-job-recruitment/127488-free-program-im-sharing-convertenumtostrings.html
Jalankan program dengan argumen "--help" untuk mendapatkan penjelasan bagaimana menggunakannya.
sumber
Belum lama ini saya membuat beberapa trik agar enum ditampilkan dengan benar di QComboBox dan memiliki definisi representasi enum dan string sebagai satu pernyataan
Sekarang Anda
enumeration::enum_singleton<your_enum>::instance()
bisa mengubah enum menjadi string. Jika Anda menggantikv_storage_t
denganboost::bimap
, Anda juga dapat melakukan konversi mundur. Kelas dasar umum untuk konverter diperkenalkan untuk menyimpannya di objek Qt, karena objek Qt tidak bisa menjadi templatePenampilan sebelumnya
sumber
Sebagai varian, gunakan lib sederhana> http://codeproject.com/Articles/42035/Enum-to-String-and-Vice-Versa-in-C
Di dalam kode
tambahkan garis
Bekerja dengan baik, jika nilai dalam enum tidak dipublikasikan .
Contoh penggunaan
dan sebaliknya
sumber
Berikut ini adalah upaya untuk mendapatkan << dan >> operator streaming pada enum secara otomatis dengan hanya perintah makro satu baris ...
Definisi:
Pemakaian:
Tidak yakin tentang batasan skema ini ... komentar dipersilakan!
sumber
sumber