使用具有可变数量参数的宏编写函数

jml*_*pez 2 c++

你如何编写一个具有可变数量的参数的宏来定义一个函数?假设我们class1用2个参数定义类,class2用3个参数定义类.

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) {}
};
Run Code Online (Sandbox Code Playgroud)

对于我定义的每个类,甚至是在我想要编写以下内容之前定义的类:

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);
}
Run Code Online (Sandbox Code Playgroud)

我们不需要关心的定义writeAmount,writeNamewriteInfo.我想做的是写一些类似的东西:

MACROWRITEINFO(class1, 2, arg1, arg2);
MACROWRITEINFO(class2, 3, arg1, arg2, arg3);
Run Code Online (Sandbox Code Playgroud)

是否可以创建这样的宏,以便它可以扩展到上面的模板定义?我已经在很多地方读到了宏是邪恶的,但在这种情况下我相信它们非常有用,因为它们会减少我输入的代码量,从而减少我在创建过程中会产生的拼写错误.模板功能.

gwi*_*rrr 5

首先,您应该改进格式/代码.您的代码在类定义后缺少"类"关键字和分号 - 当您发布代码段时,请确保它是正确的代码,因为有些人(即我)会尝试编译它.

其次,不要使用函数模板专门化.如果宏是邪恶的,那么它们必须是撒旦的化身.坚持好旧的超载.详情请见此处.

至少 - 一个答案.如果所有 args属于同一类型,你可以乱用可变参数宏- 例如,你可以在writeInfo函数内创建一个数组并迭代元素.由于这里的情况并非如此,因此您可以为不同数量的参数定义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()                \
}
Run Code Online (Sandbox Code Playgroud)

使用这些,您现在可以根据参数的数量定义变体.

#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()
Run Code Online (Sandbox Code Playgroud)

等等...

编辑:嗯,我想这可以在这里使用复杂的宏.看看这个SO问题.这是纯粹的疯狂,但你应该能够实现你想要的.

编辑:我的想法是将可变参数扩展到数组然后迭代它们; 如果他们属于同一类型,让我们说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);
Run Code Online (Sandbox Code Playgroud)

因此,如果所有变量都属于同一类型,则可以将它们放在数组中.但它们不是,所以它不会这样做.如果你真的,真的想坚持变量参​​数请转到我的第一次编辑.