2015-04-12 74 views
1

我有一些C++代碼,看起來像這樣:檢查預處理宏是否是C字符串?

std::string DataDirHelper(const std::string& file) {  
    #ifndef CRYPTOPP_DATA_DIR 
    return file; 
    #else 
    std::string dataDir(CRYPTOPP_DATA_DIR); 
    ... 
    #endif 
} 

有沒有一種方法來測試CRYPTOPP_DATA_DIR是C-stirng(而不是,比方說,一個int)?

如果是這樣,我該怎麼做?

+0

難道你不只是得到一個編譯錯誤,如果它是一個詮釋? –

+0

這似乎是一個奇怪的事情來測試,就像試圖在for循環體內斷言你沒有意外地聲明'i'是一個字符串。你爲什麼需要這樣做? – user2357112

+0

@ user2357112 - 問題是用戶定義了'CRYPTOPP_DATA_DIR',而不是庫。只要允許用戶做出選擇,我們就必須爲意想不到的事情做好計劃。主知道他們可能會想出什麼...... – jww

回答

3

最簡單的解決辦法是:

std::string DataDirHelper(const std::string& file) {  
    #ifndef CRYPTOPP_DATA_DIR 
    return file; 
    #else 
    std::string dataDir("" CRYPTOPP_DATA_DIR); 
    ... 
    #endif 
} 

CRYPTOPP_DATA_DIR時是一個字符串,編譯器將與相鄰的空字符串合併。當它不是一個字符串文字時,如果這個宏足夠糟糕,它仍然可以編譯(帶有一些前導逗號以及什麼不是)。

或者,我們可以使用static_assert需要字符串文字作爲參數的要求。因此,我們可以寫這樣的代碼:

std::string DataDirHelper(const std::string& file) {  
    static_assert(true, CRYPTOPP_DATA_DIR); 
    std::string dataDir("" CRYPTOPP_DATA_DIR); 
    ... 
} 

如果CRYPTOPP_DATA_DIR不是字符串文字,你會看到這樣的錯誤消息:

foo.cc:12:9: error: expected string literal 
static_assert(true, CRYPTOPP_DATA_DIR); 
        ^~~~~~~~~~~~~~~~~ 
+0

@jww:我在答案中添加了一些實際文字。 –

+0

謝謝@Bill。根據你引用的另一個問題,這應該作爲重複來結束嗎?如果是這樣,我會投第一關(我不知道他們有多相似)。 – jww

+0

@jww:他們非常相似。我已經把它作爲一個副本關閉了,因爲你並不擔心。 –