[英]How to pass string argument to macro
我正在嘗試使用以下代碼打印IT SUCCESS\\nET SUCCESS\\n
但編譯失敗並出現error: 'printds' was not declared in this scope
,我知道這是因為它將宏輸入作為ds
文字。 有誰知道如何做到這一點? 用例是有幾個 printXX() 函數應該根據宏中傳遞的值調用。
#include <stdio.h>
#define FOO(val) { \
print ## val(); \
}
void printIT() { printf("IT SUCCESS\n"); }
void printET() { printf("ET SUCCESS\n"); }
int main() {
const char* ds = "IT", es = "ET";
FOO(ds); FOO(es);
return 0;
}
你可以改變
FOO(ds); FOO(es);
到
FOO(IT); FOO(ET);
因為宏替換發生在您的代碼編譯之前。
但是您可以定義一個名為 FOO 的函數,例如
#include <stdio.h>
#include <iostream>
using namespace std;
void printIT() { printf("IT SUCCESS\n"); }
void printET() { printf("ET SUCCESS\n"); }
void FOO(const string str)
{
if(str=="IT")
printIT();
else
printET();
}
int main()
{
const char* ds = "IT",*es="ET";
FOO(ds);FOO(es);
return 0;
}
它將宏輸入作為
ds
文字。
是的,這是可以預料的。 預處理器宏在編譯時擴展。 類函數宏的參數是出現在宏調用中括號之間的文字源代碼標記。 這些對預處理器沒有額外的意義。
有誰知道如何做到這一點? 用例是有幾個 printXX() 函數應該根據宏中傳遞的值調用。
同樣,宏在編譯時被擴展為源代碼(大約)。 該過程沒有也不能考慮 C++ 運行時語義,例如將變量的標識符轉換為相應的值。
如果您所追求的是基於變量值的運行時動態函數調度,那么您需要一種完全不同的機制。 例如,您可以使用普通條件語句在不同的函數調用之間進行選擇。 如果您想要更加動態,那么您可以考慮准備一個函數指針查找表,並使用它來選擇和調用適當的函數。
在評論中,您添加了
我有幾種方法
queryServers
,queryNodes
,queryTargets
我想使用上述技巧調用它們。
您可以通過模板或重載函數完成與您要求的類似的事情。 這些機制也在編譯時運行,因此它們無法訪問諸如變量值之類的運行時信息,但它們確實了解並依賴於 C++ 數據類型。
或者,您可能正在尋找Strategy 模式。
您需要知道的第一件事是宏是預處理器指令,它們是具有給定名稱的代碼片段。 如果您在程序中使用宏名稱,它將將該代碼片段替換到您在編譯時第一階段使用宏名稱的地方,稱為預處理階段。
#include <stdio.h>
#define FOO(val) { \
print ## val(); \
}
void printIT() { printf("IT SUCCESS\n"); }
void printET() { printf("ET SUCCESS\n"); }
int main() {
const char* ds = "IT", es = "ET";
FOO(ds); FOO(es);
return 0;
}
在您的代碼中,您嘗試像宏一樣將 ds 和 es 變量輸入到 FOO 函數中。 但是 ds 和 es 變量只有在運行程序時才在程序棧中聲明。 在編譯時,它只是將它們視為文本。 因此宏函數輸入它作為文本 ds 和 es 並替換為 val。 這就是您收到編譯時錯誤的原因。 我更改的以下代碼片段按您的預期工作。
#include <stdio.h>
#define FOO(val) { \
print ## val(); \
}
void printIT() { printf("IT SUCCESS\n"); }
void printET() { printf("ET SUCCESS\n"); }
int main() {
const char* ds = "IT", *es = "ET";
FOO(IT); FOO(ET);
return 0;
}
如果您有興趣,可以在以下資源中找到有關宏的更多信息。 GCC 在線文檔和關於宏的文章。 此外,您可以使用g++ -E (your cpp file name)
查看預處理代碼。 謝謝。
沒有宏的可能解決方案:
void printIT() { printf("IT SUCCESS\n"); }
void printET() { printf("ET SUCCESS\n"); }
void foo(std::string_view s)
{
static const std::map<std::string_view, void(*)()> funcs{
{"IT", &printIT},
{"ET", &printET}
};
auto it = funcs.find(s);
if (it != funcs.end()) {
(*it->second)();
}
}
int main() {
const char* ds = "IT";
const char* es = "ET";
foo(ds); foo(es);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.