2011-04-10 42 views
2

C預處理器將源文本拆分爲令牌並僅執行與這些令牌匹配的擴展。通常這是預期的行爲,但有時不是。展開預處理器令牌的一部分

以這個例子爲例,我想以一種很好的方式實現一些類似模板的功能。通常它的實現是這樣的:

#define add_function_template(mytype) \ 
    mytype add_##mytype(mytype a, mytype b) { \ 
     return a + b; \ 
    } 

級聯運算符##使這一擴大,但與反斜線引用整體功能非常麻煩。是否有可能爲宏體外的函數名稱做類似的擴展?

E.g.像

#define TYPENAME int 
TYPENAME add_TYPENAME(TYPENAME a, TYPENAME b) { 
    return a + b; 
} 

標識符add_TYPENAME沒有展開,其餘的是。沒有,我如何擴展這樣的標識符?輔助宏也可以,但我找不到任何理智的方法...

回答

4

你不能用C預處理器來做到這一點。預處理令牌(如add_TYPENAME)不能拆分。最簡單的「解決方案」是一個有點難看:

#define CONCAT_IMPL(x, y) x ## y 
#define CONCAT(x, y) CONCAT_IMPL(x, y) 
#define MAKE_TYPENAME_FUNCTION_NAME(x) CONCAT(x, TYPENAME) 

TYPENAME MAKE_TYPENAME_FUNCTION_NAME(add_)(TYPENAME a, TYPENAME b) { 

具有反斜線引用整體功能非常麻煩

這可能是麻煩的,但它的使用成本任何不重要的預處理器。

+0

這絕對是一個有點醜陋,但如果預處理器兼容性好,我認爲它是可用的。 – dietr 2011-04-10 22:55:45

2

你不能這樣做。想想它是如何搞砸一個人的代碼的。

#define p f

的printf()將擴大爲frintf()

#define . ,

等等...

+0

我意識到這一點,這就是爲什麼我指出使用助手宏。 – dietr 2011-04-10 22:52:19

+0

我明白了...希望以另一種方式解決... – gd1 2011-04-11 05:53:32

0

你可以達到你想要的東西,如果你願意從另一個.c文件中包含一個.c文件。

這裏是你將如何做到這一點的例子:

add_function_template.c:

#define add_function(t) t add_##t(t a, t b) // This line could be moved elsewhere. 
add_function(mytype) 
{ 
    return a + b; 
} 

footype.c:

#define mytype footype 
#include <add_function_template.c>