[英]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);
}
我们不需要关心writeAmount
、 writeName
或writeInfo
的定义。 我想做的是写这样的东西:
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.