2012-02-23 51 views
8

考慮一個簡單的宏:在無括號的宏中使用逗號:如何混合並匹配模板?

#define ECHO(x) x 

ECHO(foo(1, 2)) 

這會產生我們期望的準確輸出:

foo(1, 2) 

上面的例子工程,因爲靠近函數調用的括號由預處理認可。

現在考慮如果我使用一個模板,而不是一個函數調用發生了什麼:

ECHO(template<int, bool>) 

因爲預處理器解釋template<intbool>作爲兩個單獨的參數傳遞給宏這將導致一個錯誤。預處理器不能識別範圍<>

無論如何在宏中使用這樣的模板?

+0

可能重複: //堆棧溢出。COM /問題/ 5348077/C-宏觀問題的解釋-的逗號 – 2012-02-23 16:06:16

+1

@OliCharlesworth啊),我沒有找到一個在我的搜索。答案似乎有不回答我的問題,準確,但它確實發人深思一些食物。謝謝。 – chrisaycock 2012-02-23 16:09:57

+0

一個較新的問題,有一些優秀的答案:http://stackoverflow.com/questions/13842468/comma-in-cc-macro/13842784#13842784 – jjrv 2014-07-17 05:35:53

回答

11
#define COMMA , 
ECHO(template<int COMMA bool>) 

有點痛苦,但它的工作原理。

FWIW,如果參數中的語法允許() S,你不需要替換,例如,

ECHO((a, b)) 

將單個參數宏工作,但並不適用於所有情況(包括你的)。

+2

注意,你有'BOOST_PP_COMMA'如果你可以包括'「升壓/預處理/標點/ comma.hpp「'。 http://www.boost.org/doc/libs/1_31_0/libs/preprocessor/doc/ref/comma.html – alfC 2012-12-13 05:40:44

1

,如果你允許的Cog使用在你的項目,你的代碼變得更容易閱讀:

/*[[[cog 
# definitions ---- 
import cog 

def AddDeclaration(templateArg , restOfDeclaration): 
    cog.outl(' %s struct %s; ' % (templateArg , restOfDeclaration)) 

# generation --- 
types = ['bool' , 'std::string'] 
names = ['Foo' , 'Bar'] 
for index in range(len(names)): 
    AddDeclaration('template<int, %s>' % types[index] , names[index]) 
]]]*/ 
//[[[end]]] 

你在這個文件運行後嵌齒輪,你會得到:

/*[[[cog 
# definitions ---- 
import cog 

def AddDeclaration(templateArg , restOfDeclaration): 
    cog.outl(' %s struct %s; ' % (templateArg , restOfDeclaration)) 

# generation --- 
types = ['bool' , 'std::string'] 
names = ['Foo' , 'Bar'] 
for index in range(len(names)): 
    AddDeclaration('template<int, %s>' % types[index] , names[index]) 
]]]*/ 
template<int, bool> struct Foo; <---------------- generated by Cog!! 
template<int, std::string> struct Bar; 
//[[[end]]] 

你甚至可以將您的定義移至單獨的.py文件中,並且齒輪部分將如下所示:


declarations.py

import cog 

def AddDeclaration(templateArg , restOfDeclaration): 
    cog.outl(' %s struct %s; ' % (templateArg , restOfDeclaration)) 

my.h

/*[[[cog 
# definitions ---- 
import declarations 
# generation --- 
types = ['bool' , 'std::string'] 
names = ['Foo' , 'Bar'] 
for index in range(len(names)): 
    AddDeclaration('template<int, %s>' % types[index] , names[index]) 
]]]*/ 
template<int, bool> struct Foo; 
template<int, std::string> struct Bar; 
//[[[end]]] 

使用COG的主要優點是,你獲得你的代碼生成的完全控制,完全使用升壓預處理或東西避免混亂不可讀像那樣。

最主要的缺點是你添加了一個新的工具依賴項到你的項目中,也因爲你需要用cog section markers來註釋它的用法,它實際上可能比手動編寫小的用法更糟糕。這是值得的,當你需要聲明的大枚舉或很多不可避免的樣板代碼

5

一個可變參數宏可以幫助:

#define ECHO(x...) x 

ECHO(foo(1, 2)) 
ECHO(template<int, bool>) 
[C++宏觀問題(逗號解釋)(HTTP的
+2

注意,這裏使用GNU擴展。標準(C++ 11)的方法是'#定義ECHO(...)__VA_ARGS__'。 – a3f 2015-12-25 19:27:25