我想写一些c ++宏代码来转换:
#define FRUITS Apple Banana Plum
EXPAND(FRUITS)
成:
void eat(Apple& instanceApple);
void eat(Banana& instanceBanana);
void eat(Plum& instancePlum);
是否可以编写EXPAND()函数来实现我的目标?
我意识到这看起来不像是一个好的编程实践,但我必须链接到具有特定接口的第三方库,并且这样做的能力将允许我在我自己的代码中避免大的重复代码块
编辑:稍微改变了我的玩具示例。
答案 0 :(得分:3)
我并不是说这对可读性有很大帮助,但它使用Boost.Preprocessor做你想做的事情:
#define DECLARE_VAR(r, data, type) type BOOST_PP_CAT(instance,type);
#define EXPAND(seq) BOOST_PP_SEQ_FOR_EACH(DECLARE_VAR,,seq)
现在您可以按如下方式定义水果列表:
#define FRUITS (Apple)(Banana)(Plum)
然后您可以使用EXPAND(FRUITS)
生成变量声明。有关完整示例see here。
根据要求,每行打印一个水果的技术相同:
#include <iostream>
#include <boost/preprocessor.hpp>
#define PER_LINE(r, data, type) BOOST_PP_STRINGIZE(type) "\n"
#define EXPAND(seq) BOOST_PP_SEQ_FOR_EACH(PER_LINE,,seq)
#define FRUITS (Apple)(Banana)(Plum)
int main() {
std::cout << EXPAND(FRUITS);
}
答案 1 :(得分:0)
没有时间解释,但我刚刚做了这个:
struct A
{
int i;
A(){i=1;}
void quack() {std::cout << "A" << i << std::endl;}
};
struct B
{
int i;
B(){i=2;}
void quack() {std::cout << "B" << i << std::endl;}
};
struct C
{
int i;
C(){i=3;}
void quack() {std::cout << "C" << i << std::endl;}
};
#include <tuple>
std::tuple<A,B,C> tupl;
struct quacker
{
template <typename T>
void operator()(T& t)
{
t.quack();
}
};
template <typename Q,std::size_t index, typename... Ts>
typename std::enable_if<
index < sizeof...(Ts) >::type foo_helper(Q q,std::tuple<Ts...>& ts)
{
q(std::get<index>(ts));
foo_helper<Q,index+1,Ts...>(q,ts);
}
template <typename Q,std::size_t index, typename... Ts>
typename std::enable_if<
index >= sizeof...(Ts) >::type foo_helper(Q q,std::tuple<Ts...>& ts)
{
}
template <typename Q, typename... Ts>
void foo(Q q,std::tuple<Ts...> ts)
{
foo_helper<Q,0,Ts...>(q,ts);
}
int main(int argc,char** argv)
{
foo(quacker(),tupl);
}