-1

I often use const lookup tables in my code, which consists of an id and a string. But for readability it would be better to use symbol names (named constants) instead of the id. Example:

class LookupTable
{
   map<int,string> m { {10,"red"}, {20,"blue"}, {30,"green"} };
   enum { col_rd = 10, col_bl = 20, col_gr = 30 };
};

LookupTable tab;
cout << tab.m[10];      // "red", using the id
cout << tab.m[col_bl]   // "blue", using a symbol

cout << tab.m[11];      // Typo! Compiler does not check this
cout << tab.m[col_xy];  // Typo! Compiler will complain

Using symbol names will also be checked for typos at compile time.

But I like to define the symbol name, the id and the string for a element in one place, instead of defining the values in the upper part and then defining the named constants in the lower part of the class declaration, especially if the table is quite long. For example I would like to write something like:

mytable.init = { { col_rd, 10, "red" },    // define the symbol names and 
                 { col_bl, 20, "blue" },   // values at one place
                 { col_gr, 30, "green" } };

Is this possible to do by templates or in combination with #define macros?

Ashkan Mobayen Khiabani
  • 33,575
  • 33
  • 102
  • 171
ThomasG
  • 3
  • 2

2 Answers2

5

The id seems useless to me. Can't you do the following ?

struct LookupTable
{
    enum ColorType
    {
        col_rd,
        col_bl,
        col_gr
    }

    std::map<ColorType, std::string> m;
};

Then, you could do something like :

LookupTable table;

table.m = {{LookupTable::col_rd, "red"},
           {LookupTable::col_bl, "blue"},
           {LookupTable::col_rd, "green"}};
πάντα ῥεῖ
  • 1
  • 13
  • 116
  • 190
Unda
  • 1,827
  • 3
  • 23
  • 35
  • @πάντα ῥεῖ I used a class and a public field in case his `LookupTable` was not as simple as written in his question. Anyway if you want to use a `struct`, you should also remove the `public` keyword before the `m` field (I've done it : see the edit workflow). – Unda Jun 20 '14 at 12:35
  • The enum values wouldn't have been accessible otherwise There are still some minor syntax errors though, edited again ... – πάντα ῥεῖ Jun 20 '14 at 12:39
  • You're right, thanks for the fix (I'm overwhelmed by java right now, sorry). – Unda Jun 20 '14 at 12:42
  • Thank you for your help. But I still need an id. Maybe some other routines accepts specific numeric values (e.g. for colors) instead of strings or the implicit index of the enum. – ThomasG Jun 20 '14 at 13:44
3

I once saw this technique used in the Varnish cache, it uses macros - but you say you are ok with that :)

In color_tags.hpp:

// Define the color tags

COLOR_TAG(col_rd, 10, "red")
COLOR_TAG(col_bl, 20, "blue")
COLOR_TAG(col_gr, 30, "green")

Usage in main.cpp:

#include <map>
#include <string>
#include <iostream>

/// Enumeration of different color codes, we use a bit of
/// macro uglyness to makes this easy
enum class color_type
{
    #define COLOR_TAG(id,value, msg) id = value,
    #include "color_tags.hpp"
    #undef COLOR_TAG
    terminate_tag
};

int main()
{
    std::map<color_type, std::string> m =
    {
        #define COLOR_TAG(id, value, msg) {color_type::id, msg},
        #include "color_tags.hpp"
        #undef COLOR_TAG
        {color_type::terminate_tag, "undefined"}
    };

    std::cout << m[color_type::col_rd] << std::endl;
    std::cout << m[color_type::col_bl] << std::endl;
    std::cout << m[color_type::col_gr] << std::endl;

    return 0;
}

Output:

$ g++ main.cpp -std=c++11
$ ./a.out 
red
blue
green
mortenvp
  • 1,095
  • 1
  • 7
  • 13
  • Thank you for your answer. Youre right. The problem is to split my whish of a compact description into 2 areas. One with the enum and one for the map. And your solution with include files is a funny way, but definitely it is of valueable help. Thank you for your fast and descriptive solution. Best regards, Thomas – ThomasG Jun 20 '14 at 13:48
  • Using [macros is bad](http://stackoverflow.com/questions/4715831/why-is-define-bad-and-what-is-the-proper-substitute)... – Kyle_the_hacker Jun 26 '14 at 12:26