用整数编译字符串常量的时间替换

时间:2016-06-28 19:36:23

标签: c++ c++11

我有一个预定义的字符串常量映射列表到数字之外的数字 我的代码库。整数映射到程序内部的数据,但我想在代码中使用更易读的字符串常量。生成的二进制文件应仅包含数字,并且根本不包含字符串常量。是否可以在编译时用映射的整数替换字符串常量?

我想要实现的基本上是这个代码:

Visisble

我希望将其转化为:

getData("a string constant here");

这可以通过宏或constexpr吗?

5 个答案:

答案 0 :(得分:5)

#define astrconst 277562452

或者

enum Strs { astrconst = 277562452 };

答案 1 :(得分:4)

您可以使用自定义后缀(请参阅user-defined literals

这将使用如下:

getData("a string constant here"_hash);

或者只是使用consexpr哈希函数:

getData(hash("a string constant here"));

有一些constexpr哈希函数out there

的例子

编辑:如果已经定义了映射,我的答案将不会有多大帮助......

答案 2 :(得分:1)

您可以使用您在内部定义的宏来执行此操作,例如

#define A_STRING_CONSTANT_HERE 277562452

或在命令行外部。命令行依赖于编译器。对于GNU编译器,您可以使用-D指令,即

g++ -DA_STRING_CONSTANT_HERE=277562452 myprog.cpp

然后你就这样使用它:

getData(A_STRING_CONSTANT_HERE);

您的常量名称将成为您的代码的一部分;它会被数字值替换,就像你写的那样

getData(277562452);

答案 3 :(得分:1)

只需使用const auto a_string_constant_here = 277562452;即可。然后,只要您想引用常量,就使用a_string_constant_here

答案 4 :(得分:1)

我认为基于枚举(参见Ivan Rubinson)或定义(参见dasblinkenlight)的解决方案更可取。

但是如果你真的想在你的代码中使用C风格的字符串,并在编译fase中抛弃它们,我提出以下解决方案,基于constexpr函数和三个宏函数

#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;
 }

strCmp() constexpr函数大致相当于std::strcmp(),但区别在于左边字符串中的空格被认为等于右边字符串中的下划线。

接下来,您可以使用定义

创建地图字符串/数字
#define  string_constant_1   123456

是宏string_constant_1对应于C风格的字符串(“字符串常量1”)。我的意思是:字符串中的空格在宏名称中变为下划线。

宏功能GetIntValue()ChkStr()IfFragm()正在进行肮脏的工作。

但我认为宏是C / C ++的邪恶部分所以我建议使用enum或简单地定义基于解决方案。

p.s:抱歉我的英语不好。