I think that solution based on enums (see Ivan Rubinson) or defines (see dasblinkenlight) are preferable.
But if you really want to use C-style string in your code, and throw they away in compiling fase, I propose the following solution, based on a constexpr
function and three macro function
#include <iostream>
constexpr int strCmp (char const * s1, char const * s2)
{
return ((0 == *s1) && (0 == *s2))
? 0
: ((*s1 == *s2) || ((*s1 == ' ') && (*s2 == '_')))
? strCmp(s1+1, s2+1)
: (*s1 - *s2);
}
#define string_constant_1 123456
#define string_constant_2 345678
#define string_constant_3 567890
#define IfFragm(c, i) ( 0 == c ) ? i
#define ChkStr(STR, CST) IfFragm(strCmp(STR, #CST), CST)
#define GetIntValue(STR) (ChkStr(STR, string_constant_1) \
: ChkStr(STR, string_constant_2) \
: ChkStr(STR, string_constant_3) \
: 0)
int main ()
{
std::cout << "val 1 = " << GetIntValue("string constant 1") << std::endl;
std::cout << "val 2 = " << GetIntValue("string constant 2") << std::endl;
std::cout << "val 3 = " << GetIntValue("string constant 3") << std::endl;
return 0;
}
The strCmp()
constexpr
function is roughly equivalent to std::strcmp()
but with the difference that a space in the left string is considered equal to an underscore in the right string.
Next you can create your maps string/number using defines
#define string_constant_1 123456
were the macro string_constant_1
correspond to the C-style string ("string constant 1"). I mean: the spaces in the string are become underscores in the macro name.
The macro functions GetIntValue()
, ChkStr()
and IfFragm()
are doing the dirty work.
But I think that macros are evil part of C/C++ so I suggest the enum or simply define based solution.
p.s.: sorry for my bad English.