我正在尝试根据参数的数量重载c ++预处理器宏。
例如,我想这样做:
FOO(1, 2, 3) //==> expandsto FOO3(1,2,3)
FOO(1, 2) //==> expandsto FOO2(1,2)
这就是我所做的:
#define GET_MACRO(_1,_2,_3,NAME,...) NAME
#define FOO(...) GET_MACRO(__VA_ARGS__, FOO3, FOO2)(__VA_ARGS__)
#define FOO2(A, B) std::cout<<"2 arguments"<<std::endl;
#define FOO3(A, B, C) std::cout<<"3 arguments"<<std::endl;
int main() {
FOO(1,2,3)
return 0;
}
但是,在VC ++中,上面的确切代码给出了编译器错误:
expected a ";"
我做错了什么..?
更新
事实上,我意识到这适用于Ideone >>>LINK<<< ......它不适用于Visual Studio 12 .. 为什么这个..如果VS不支持这种类型的宏重载......有哪些替代方案..?
由于
答案 0 :(得分:4)
这是__VA_ARGS__
试试这个
#define ID(x) x
#define GET_MACRO(_1,_2,_3,NAME,...) NAME
#define FOO(...) ID(GET_MACRO(__VA_ARGS__, FOO3, FOO2)(__VA_ARGS__))
答案 1 :(得分:2)
看起来它是Visual Studio的bug,你的代码是有效的(我可以用GCC编译它)。但无论如何它的风格都很糟糕。
#define FOO2(A, B) std::cout<<"2 arguments"<<std::endl; // add `do {...} while (0)` construction
#define FOO3(A, B, C) std::cout<<"3 arguments"<<std::endl;
int main() {
FOO(1,2,3) // Put `;` here
return 0;
}
代码应如下所示:
#define FOO2(A, B) do {std::cout<<"2 arguments"<<std::endl;} while (0)
#define FOO3(A, B, C) do {std::cout<<"3 arguments"<<std::endl;} while (0)
int main() {
FOO(1,2,3); // Looks like normal function now!
return 0;
}
你可能会问,do {} while (0)
是什么东西?它阻止程序员像这样使用您的宏:FOO2(1, 2) << "text";
。