2014-07-03 30 views
3

我想這樣做如下:如何對範圍運算符使用令牌連接?

#define CODE_BLOCK(id) \ 
    do { \ 
     someNameSpace::##id foo; \ 
     foo.ParseFromString(...); \ 
     print_##id(foo); 
    } while(0) 
[...] 
CODE_BLOCK(BlahStream); 

所以基本上,我想FOO聲明爲類型someNameSpace :: ID其中,ID宏參數。 print_id在別處定義。無論如何,g ++抱怨的消息:

error: pasting "::" and "BlahStream" does not give a valid preprocessing token 

反正有這個嗎?

如果有幫助,foo來自某個用戶定義的googleprotocol緩衝區。我的g ++版本在debian linux上是4.7.2。

謝謝。

回答

7

只需刪除##運營商,它會工作得很好。

例如

#define stuff(x) \ 
    std:: x 

#include <iostream> 

int main() { 
    stuff(cout) << "Hello World\n"; 
} 
+0

謝謝!這似乎奏效了。你爲我節省了很多工作。該宏比示例稍大。 (當我被允許時,我會檢查你的標記,我的帖子上有一個隱藏的計時器。) – Bitdiot

+0

謝謝Rapptz,今天幫助我 – Arun

7

預處理已經意識到x::y是三個獨立的標記:x::y

因此,您不需要任何串聯,事實上,正如您發現的那樣,嘗試使用它將導致錯誤。

當你這樣寫:

someNameSpace::##id 

你寫someNamespace::y&hellip;和::y不是一個單一的標記。

你只要簡單地寫:

someNameSpace::id 

現在你有someNamespace::y&hellip;如預期的。

這是你完成的代碼:

#define CODE_BLOCK(id) \ 
    do { \ 
     someNameSpace::id foo; \ 
     foo.ParseFromString(...); \ 
     print_##id(foo); 
    } while(0) 
// [...] 
CODE_BLOCK(BlahStream); 

注:我已經刪除了在(符號之後繼續寫入的空格,因爲是新的。 :)

+1

哇!這很棒。感謝您的清楚解釋。 – Bitdiot

+0

@Bitdiot:你非常歡迎。 :) –