2016-06-28 39 views
3

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

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

getData("a string constant here"); 

,我希望把它改造成这样:

getData(277562452); 

这是可能通过宏或constexpr?

+6

为什么不使用命名常量?包含“const int a_string_constant_here = 277562452;'等行的文件 – amaurea

回答

5
#define astrconst 277562452 

或者

enum Strs { astrconst = 277562452 }; 
+1

宏名称必须是标识符,而不是字符串文字。 – interjay

+0

我就此赌钱。谢谢,编辑 –

1

您可以用您定义在内部宏做,这样

#define A_STRING_CONSTANT_HERE 277562452 
在命令行上

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

g++ -DA_STRING_CONSTANT_HERE=277562452 myprog.cpp 

然后你使用这样的:

getData(A_STRING_CONSTANT_HERE); 

你常数将的名称不是你的代码的一部分;它会用数值来代替,因为如果你写

getData(277562452); 
4

你可以使用自定义的后缀(见user-defined literals

这将用于像此:

getData("a string constant here"_hash); 

或简单地使用consexpr哈希函数:中constexpr散列函数

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

有例子out there

编辑:如果映射已经被定义,我的回答不会帮助不大...

+1

即使对这个要求没什么帮助,我也学会了用户定义的文字。感谢张贴这! – xen

1

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

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++的邪恶部分,所以我建议枚举或简单地定义基于解决方案。

对不起,我的英语不好。

+0

谢谢发布!我选择使用基于枚举的方法,因为从输入数据和解决方案中生成这些数据非常容易,而看起来正是我想要的,看起来非常令人生畏,我确信我不记得它做了什么。月下来:D – xen

+0

@xen - 不错的选择;我认为这枚枚举是更好的方法,我已经提升了伊万鲁宾逊的解决方案;我提出我的解决方案只是因为很难实现,但我认为这不是一个好的解决方案。 – max66