在宏中,我可以使用xxxx _ ## TYPE和## TYPE ## _ xxxxx來正確填寫TYPE名稱,但是我不能使用## TYPE ##在一個字符串的中間,例如(打印「## TYPE ##是類型的名稱」;)C++宏謎語:打印類型的名稱
是否有解決方法?
在宏中,我可以使用xxxx _ ## TYPE和## TYPE ## _ xxxxx來正確填寫TYPE名稱,但是我不能使用## TYPE ##在一個字符串的中間,例如(打印「## TYPE ##是類型的名稱」;)C++宏謎語:打印類型的名稱
是否有解決方法?
您可以通過組合兩個功能來做到這一點。一種是「字符串化」,通過將其前綴爲#
,將宏參數轉換爲字符串。 (這與你明顯已經熟悉的'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
,你絕對可以)
##
是token pasting operator,它需要兩個不同的令牌,共同它們粘貼到m。使用單個令牌。整個字符串文字被認爲是一個單一的標記,因此粘貼操作符不能在其中工作。請參閱http://gcc.gnu.org/onlinedocs/gcc-4.0.4/cpp/Tokenization.html
是的,但你不回答他的問題。 – Kleist
@Kleist,因爲我無法改進ruakh的答案 - 我已經給了我的+1。我只是認爲這是重要的背景信息,需要在那裏。 –
字符串文字在它們相鄰時將被連接。
#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;
}
爲什麼不添加一個簡單的例子,即使你不知道他將如何使用它?可以是'#define TYPESTRING(TYPE)「字符串,typename:」#TYPE「正好在中間。」'例如。 – Kleist
@Kleist:O.K.,完成。我不相信它比鏈接到GCC文檔更有用,但它肯定不會受到傷害。 :-) – ruakh