我哈瓦宏调用静态函数为每个ARGS。
例如:
#define FOO(X) X::do();
#define FOO_1(X,Y) X::do(); Y::do();
我的问题是,我需要使用foo且可变的参数个数,是否有可能使用__VA_ARGS__
?
像下面的一行:
#define FOO(...) __VA_ARGS__::do() ?
谢谢
我哈瓦宏调用静态函数为每个ARGS。
例如:
#define FOO(X) X::do();
#define FOO_1(X,Y) X::do(); Y::do();
我的问题是,我需要使用foo且可变的参数个数,是否有可能使用__VA_ARGS__
?
像下面的一行:
#define FOO(...) __VA_ARGS__::do() ?
谢谢
宏扩展不起作用像参数包扩展与可变参数模板。 你有什么会扩展为:
X,Y::do();
而不是
X::do(); Y::do();
正如你希望的。 但在C ++ 11可以使用可变参数模板。 举例来说,你可以做你想做的是这样的:
#include <iostream>
struct X { static void foo() { std::cout << "X::foo()" << std::endl; }; };
struct Y { static void foo() { std::cout << "Y::foo()" << std::endl; }; };
struct Z { static void foo() { std::cout << "Z::foo()" << std::endl; }; };
int main()
{
do_foo<X, Y, Z>();
}
所有你需要的是这样的(相对简单)机械:
namespace detail
{
template<typename... Ts>
struct do_foo;
template<typename T, typename... Ts>
struct do_foo<T, Ts...>
{
static void call()
{
T::foo();
do_foo<Ts...>::call();
}
};
template<typename T>
struct do_foo<T>
{
static void call()
{
T::foo();
}
};
}
template<typename... Ts>
void do_foo()
{
detail::do_foo<Ts...>::call();
}
这是一个活生生的例子 。
你不能直接这样做, __VA_ARGS__
始终被视为包含所有用逗号分隔的参数的一个单元。 预处理器不提供内置的方式找到的参数的数量,把它们分开或遍历它们。
这个答案对一个类似问题显示了使用预处理的基本解决方案:了解有多少项目有您的参数列表,并把它传递到不带参数的这个确切金额的宏。
我建议你不要这样做,而是使用安迪巡游C ++ 11的解决方案 ,甚至调整你的代码,所以你不需要这些的。
其实你可以部分地解决此。
可以直接和自由既不提取的每一个成员__VA_ARGS__
也不是C ++ 11可变参数模板。 但是你可以有非常第一要素。 例如,让我们说我们有一个名为宏OUT(...)
我们希望产生的std ::法院<< A <<乙<<ç...其中A,B,C是宏的可变参数。 试试这个:
#include <iostream>
#define SEPERATOR <<
#define GET_1_OF(element1, ...) element1
#define GET_2_OF(element1, ...) element1 SEPERATOR GET_1_OF(__VA_ARGS__)
#define GET_3_OF(element1, ...) element1 SEPERATOR GET_2_OF(__VA_ARGS__)
#define BAR(...) GET_3_OF(__VA_ARGS__)
int main()
{
std::cout << BAR(1,2,3,4,5);
return 0;
}
这当然不是你后的溶液。 但是,你可以增加GET_N_OF的数量,做你想做的。 需要注意的是SEPERATOR
是<<
让我们宏可以写1 << 2 << 3
等。
现在,我们在这个代码的问题。 请更改BAR(1,2,3,4,5)
与BAR(1)
你会看到,它给了一个错误。 这是因为它期待3周的论据,虽然这不是问题,有更多的参数(因为它是可变参数),我们有额外的SEPERATOR
。 因此,为了解决,而不是使用这个问题BAR(...)
使用GET_N_OF(...)
因为你知道的参数的个数):
#include <iostream>
#define SEPERATOR <<
#define GET_1_OF(element1, ...) element1
#define GET_2_OF(element1, ...) element1 SEPERATOR GET_1_OF(__VA_ARGS__)
#define GET_3_OF(element1, ...) element1 SEPERATOR GET_2_OF(__VA_ARGS__)
#define GET_4_OF(element1, ...) element1 SEPERATOR GET_3_OF(__VA_ARGS__)
#define GET_5_OF(element1, ...) element1 SEPERATOR GET_4_OF(__VA_ARGS__)
int main()
{
std::cout << GET_5_OF(1,2,3,4,5);
std::cout << GET_1_OF(1);
return 0;
}
请注意, 如果你不知道你在做什么,都不要使用宏! 我的回答是只为了分享乐趣宏代码可能对你有利。 我总是劝阻宏的使用,直到他们是非常必要的。