繁体   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