簡體   English   中英

使用可變編號 arguments 的宏編寫 function

[英]Writing a function using a macro with variable number of arguments

你如何編寫一個可變數量的 arguments 的宏來定義一個 function? 假設我們用 2 個參數定義 class class1 ,用三個參數定義 class class2

class class1 {
public:
   int arg1;
   int arg2;
   class1(int x1, int x2): arg1(x1), arg2(x2) {}
};
class class2 {
public:
   int arg1;
   int arg2;
   int arg3;
   class1(int x1, int x2, int x3): arg1(x1), arg2(x2), arg3(x3) {}
};

對於我定義的每個 class 甚至是在我想編寫以下內容之前已經定義的類:

template<> inline void writeInfo<class1>(const class1& obj, FILE* fp) {
    writeAmount(2, fp);
    writeName("arg1", fp);
    writeInfo(obj.arg1, fp);
    writeName("arg2", fp);
    writeInfo(obj.arg2, fp);
}
template<> inline void writeInfo<class2>(const class2& obj, FILE* fp) {
    writeAmount(3, fp);
    writeName("arg1", fp);
    writeInfo(obj.arg1, fp);
    writeName("arg2", fp);
    writeInfo(obj.arg2, fp);
    writeName("arg3", fp);
    writeInfo(obj.arg3, fp);
}

我們不需要關心writeAmountwriteNamewriteInfo的定義。 我想做的是寫這樣的東西:

MACROWRITEINFO(class1, 2, arg1, arg2);
MACROWRITEINFO(class2, 3, arg1, arg2, arg3);

是否可以創建這樣的宏,以便它可以擴展到上述模板定義? 我在很多地方都讀到宏是邪惡的,但在這種情況下,我相信它們非常有幫助,因為它們會減少我輸入的代碼量,從而減少我在創建模板函數。

首先,您應該改進您的格式/代碼。 您的代碼在類定義后缺少“類”關鍵字和分號 - 當您發布片段時,請確保它是正確的代碼,因為有些人(即我)會嘗試編譯它。

其次,不要使用 function 模板專業化。 如果宏是邪惡的,那么它們一定是撒旦的化身。 只需堅持舊的重載即可。 有關詳細信息,請參見此處

至少 - 一個答案。 如果所有args 都屬於同一類型,您可能會弄亂可變參數宏 - 例如,您可以在 writeInfo function 中創建一個數組並迭代元素。 由於這里顯然不是這種情況,您可以為不同數量的參數定義 MACROWRITEINFO 宏的許多變體,使用一些通用塊來減少代碼重復。 例如:

#define MACROWRITEINFO_BEGIN(type, amount)  \
void writeInfo(const type& obj, FILE* fp)   \
{                                           \
    writeAmount(amount, fp);

#define MACROWRITEINFO_NAMEINFO(name)       \
    writeName(#name, fp);                   \
    writeInfo(obj.##name, fp);

#define MACROWRITEINFO_END()                \
}

使用這些,您現在可以根據 arguments 的數量定義變體。

#define MACROWRITEINFO1(type, arg1) \
    MACROWRITEINFO_BEGIN(type, 1)   \
    MACROWRITEINFO_NAMEINFO(arg1)   \
    MACROWRITEINFO_END()

#define MACROWRITEINFO2(type, arg1, arg2) \
    MACROWRITEINFO_BEGIN(type, 2)   \
    MACROWRITEINFO_NAMEINFO(arg1)   \
    MACROWRITEINFO_NAMEINFO(arg2)   \
    MACROWRITEINFO_END()

等等...

編輯:好吧,我想可以在這里使用可變參數宏。 看看這個SO question 這純粹是瘋狂,但你應該能夠實現你想要的。

編輯:我的想法是將可變參數 arguments 擴展為數組,然后遍歷它們; 如果它們是相同的類型,比如說 int,你可以這樣寫:

#define VAARGSSAMPLE(...) \
    int args[] = { __VA_ARGS__ }; \
    for (int i = 0; i < sizeof(args)/sizeof(int); ++i) \
    { \
        printf("%d\n", args[i]); \
    }

VAARGSSAMPLE(1, 5, 666);

因此,如果所有變量都屬於同一類型,則可以將它們放入數組中。 但他們不是,所以它不會做。 如果您真的非常想堅持使用可變參數 arguments go 進行我的第一次編輯。

我認為用宏不可能做到這一點。 您可以使用變量 arguments(可變參數),但不能生成依賴於 arguments 的代碼。

我建議您創建一個 DSL(例如簡單的 xml..)並從中生成代碼。 這是更清潔和良好的做法。

你可以這樣做:

<writeInfos>
    <writeInfo class="class1" amount="3">
        <arguments>
            <argument>arg1</argument>
            <argument>arg2</argument>
        </arguments>
    </writeInfo>
</writeInfos>

然后從中創建源代碼。 您應該在構建過程中添加此步驟..

但是你也可以定義一些更簡單的東西..你可以把你的 MACROWRITEINFO “函數”放在一個文本文件中並自己解析它..

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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