2016-06-28 65 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