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

Compile time replacement of string constants with integers

本文关键字:字符串 常量 替换 整数 编译      更新时间:2023-10-16

我有一个字符串常量到外部数字的预定义映射列表我的代码库。整数映射到程序内部的数据,但我想在代码中使用可读性强得多的字符串常量。生成的二进制文件应该只包含数字,根本不包含字符串常量。是否有可能在编译时将字符串常量替换为映射的整数?

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

getData("a string constant here");

我想把它转换成这样:

getData(277562452);

是否可以通过宏或constexpr实现?

#define astrconst 277562452

enum Strs { astrconst = 277562452 };

您可以使用自定义后缀(参见用户定义的字面量)

可以这样使用:

getData("a string constant here"_hash);

或者直接使用consexpr散列函数:

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

有constexpr哈希函数的例子

编辑:如果映射已经定义,我的回答没有多大帮助…

可以使用内部定义的宏来实现,就像这样

#define A_STRING_CONSTANT_HERE 277562452

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

g++ -DA_STRING_CONSTANT_HERE=277562452 myprog.cpp

然后像这样使用:

getData(A_STRING_CONSTANT_HERE);

你的常量的名字将而不是成为你代码的一部分;它将被替换为数字值,就像您写

一样
getData(277562452);

只用const auto a_string_constant_here = 277562452;。然后使用a_string_constant_here每当你想引用常量

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

但是如果你真的想在你的代码中使用c风格的字符串,并在编译时抛弃它们,我提出以下解决方案,基于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

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

是宏string_constant_1对应c风格的字符串("string constant 1")。我的意思是:字符串中的空格变成宏名称中的下划线。

宏函数GetIntValue(), ChkStr()IfFragm()正在做脏工作。

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

注。