Yet another static array initialization in C++ -
i have following code in c++ (c++11 available)
typedef enum { apple, orange, last, } fruits_t; template <typename t, size_t size> char (&arraysizehelper( t (&)[size]))[size]; #define arraysize(parray) sizeof(arraysizehelper(parray)) static const char *lookup_table[] { "apple", // apple "orange", // orange }; // fail compilation if lookup table missing static_assert(arraysize(lookup_table) == last, "update lookup table");
i want able change order in enumeration without changing initialisation list in lookup_table.
i have read initialization of normal array 1 default value , template need, not quite. struggled metaprogramming half day , still can not figure out how it.
the actual enumeration in code starts 0 , contains 20-30 entries. have considered hash table - hash function trivial, problem of initialization remains. have many - 5+ - lookup tables in code. worth struggle?
p.s. after couple of answers around switch construct let me show chunk of real code. 1 example.
typedef enum { events_statistics_collector_pool_timeout , events_statistics_collector_pool_failed , events_statistics_collector_sent_to_pipeline , // 50 entries events_statisitcs_last , } events_statistics_t; uint64_t events_statistics[events_statisitcs_last]; const char *event_statistics_names[] = { "collector_pool_timeout ", "collector_pool_failed ", "collector_sent_to_pipeline ", // , on ... }; static inline void events_statistics_bump_counter(events_statistics_t counter) { events_statistics[counter]++; } // actual function generic 1 prints arbitrary pairs // 1 gives idea void print_statistics() { int col = 0; static const int columns = 3; printf("\n"); (int = 0;i < events_statisitcs_last;i++) { printf("%-30s %9lu", event_statistics_names[i], events_statistics[i]); col++; if ((col % columns) == 0) printf("\n"); else printf("%4s", ""); } if ((col % columns) != 0) printf("\n"); }
p.s.2 wanted in previous p.s. "switch" gives freedom compiler. want ensure lookup simple table , not double indexed array or if/else branches
p.s.3 here example of initialised array. array contains hooks , of extreme importance call correct function.
typedef struct { const int id; const events_process_t processor; uint64_t counter; } events_process_table_t; static events_process_table_t events_processors[event_id_last] = { {event_id_open , (events_process_t)events_process_open }, {event_id_openat , (events_process_t)events_process_open }, // , on 30 lines }; static_assert(arraysize(events_processors) == event_id_last, "update table of events processors"); void some_code(int event_id) { events_process_table_t *table = &events_processors[event_id]; if (event_id == table->id) { // looks alright , can use table->processor // ..... } }
i think efficient way handle situation function maps enum values corresponding c-string:
enum class fruits { apple, orange, last }; char const* show(fruits x) { switch (x) { case fruits::apple: return "apple"; case fruits::orange: return "orange"; case fruits::last: return "last"; } assert(false); return nullptr; }
at point, if forget define fruits::last
's string in show
, compilers warn like:
main.cpp: in function 'const char* show(fruits)':
main.cpp:7:12: warning: enumeration value 'last' not handled in switch [-wswitch]
switch (x) {
which if compile -werror
prevent compilation.
Comments
Post a Comment