簡體   English   中英

如何將字符串參數傳遞給宏

[英]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++ 運行時語義,例如將變量的標識符轉換為相應的值。

如果您所追求的是基於變量值的運行時動態函數調度,那么您需要一種完全不同的機制。 例如,您可以使用普通條件語句在不同的函數調用之間進行選擇。 如果您想要更加動態,那么您可以考慮准備一個函數指針查找表,並使用它來選擇和調用適當的函數。

在評論中,您添加了

我有幾種方法queryServersqueryNodesqueryTargets我想使用上述技巧調用它們。

您可以通過模板或重載函數完成與您要求的類似的事情。 這些機制也在編譯時運行,因此它們無法訪問諸如變量值之類的運行時信息,但它們確實了解並依賴於 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM