编译时用整数替换字符串常量
Compile time replacement of string constants with integers
我有一个字符串常量到外部数字的预定义映射列表我的代码库。整数映射到程序内部的数据,但我想在代码中使用可读性强得多的字符串常量。生成的二进制文件应该只包含数字,根本不包含字符串常量。是否有可能在编译时将字符串常量替换为映射的整数?
我想要实现的基本上是这样的代码:
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或简单的基于定义的解决方案。
注。
- 将错误作为从字符串常量到"char*"的已弃用转换 [-Wwrite-strings]
- 3 与错误最接近的总和:字符串常量之前的预期非限定 id
- 为什么字符串(常量字符* s,size_t pos,size_t len = npos)有效?
- 指向字符串常量的指针
- 警告:ISO C++禁止将字符串常量转换为'char*' [-Wwrite-strings]
- 为什么在波纹管程序中发生了从字符串常量到'char*'的警告已弃用的转换
- 一种创建将字符串常量返回给枚举的类的廉价方法,反之亦然
- 如何从字符串常量创建字符数组
- 将字符串常量转换为char
- C++ 字符串常量和静态初始化顺序惨败
- 使用 std::string 返回开关大小写块中的字符串常量
- 消除从字符串常量到'char*'的已弃用转换的最佳方法"
- 警告:ISO C++禁止将静态“constexpr char*”数据成员的字符串常量转换为“char*”
- 字符常量或字符串常量
- Swig:如何类型映射c ++字符串常量和python字符串?
- 字符串常量之前的预期构造函数、析构函数或类型转换
- 为什么从字符串常量到"char*"的转换在 C 中有效,但在C++中无效
- 警告:已弃用从字符串常量到 'char* 的转换
- 无法获得通过C++警告:(和崩溃后)已弃用从字符串常量到"char*"的转换 [-Wwrite-strings]
- 错误:字符串常量 extern "a" { 之前应为非限定 ID