2011-11-30 23 views
4

在宏中,我可以使用xxxx _ ## TYPE和## TYPE ## _ xxxxx來正確填寫TYPE名稱,但是我不能使用## TYPE ##在一個字符串的中間,例如(打印「## TYPE ##是類型的名稱」;)C++宏謎語:打印類型的名稱

是否有解決方法?

回答

6

您可以通過組合兩個功能來做到這一點。一種是「字符串化」,通過將其前綴爲#,將宏參數轉換爲字符串。 (這與你明顯已經熟悉的'token-pasting'運算符##有關,但不同。)另一個事實是C++在連續給出多個字符串文字時將它們結合起來成一個單一的字符串。例如,"a" "b" "c"相當於​​。我不清楚你的宏是如何定義的,所以我不能告訴你究竟是輸入什麼,但是完整的解釋和一些好的工作示例在http://gcc.gnu.org/onlinedocs/cpp/Stringification.html


編輯補充一個簡單的例子,在克萊斯特的請求。這個程序:

#include <stdio.h> 

#define PRINT_WHAT_THE_NAME_OF_THE_TYPE_IS(TYPE) \ 
    printf("%s\n", "'" #TYPE "' is the name of the type.") 

int main() 
{ 
    PRINT_WHAT_THE_NAME_OF_THE_TYPE_IS(Mr. John Q. Type); 

    return 0; 
} 

將打印:。

(這將在C或C++運行我之所以寫這2 C ishly的是,在我的經驗,這些各種各樣的預處理程序的技巧是在C代碼中比較常見的比在現實C++代碼;但是,如果你想使用的std::cout <<代替printf,你絕對可以)

+0

爲什麼不添加一個簡單的例子,即使你不知道他將如何使用它?可以是'#define TYPESTRING(TYPE)「字符串,typename:」#TYPE「正好在中間。」'例如。 – Kleist

+0

@Kleist:O.K.,完成。我不相信它比鏈接到GCC文檔更有用,但它肯定不會受到傷害。 :-) – ruakh

1

##token pasting operator,它需要兩個不同的令牌,共同它們粘貼到m。使用單個令牌。整個字符串文字被認爲是一個單一的標記,因此粘貼操作符不能在其中工作。請參閱http://gcc.gnu.org/onlinedocs/gcc-4.0.4/cpp/Tokenization.html

+0

是的,但你不回答他的問題。 – Kleist

+0

@Kleist,因爲我無法改進ruakh的答案 - 我已經給了我的+1。我只是認爲這是重要的背景信息,需要在那裏。 –

0

字符串文字在它們相鄰時將被連接。

#define QUOTE(X) #X 

#define DOSTUFF(TYPE) \ 
    void print_ ## TYPE() { \ 
     static const char *str = QUOTE(TYPE) " is the name of the type\n"; \ 
     printf(str); \ 
    } 

DOSTUFF(Foo); 

int main(int argc, char ** argv) { 
    print_Foo(); 
    return 0; 
} 

g++ -E -c main.cpp的輸出會告訴你預處理的內容。

# 16 "main.cpp" 
void print_Foo() { 
    static const char *str = "Foo" " is the name of the type\n"; 
    printf(str); 
}; 

int main(int argc, char ** argv) { 
print_Foo(); 
return 0; 
}