考虑下面的代码:如何使用Boost MPL在函数中有多个返回点?
struct Param {};
struct Base {
virtual char f(Param const &) const = 0;
};
struct A : Base {
explicit A(Param const &) {}
virtual char f(Param const &) const {return 'A';}
};
struct B : Base {
explicit B(Param const &) {}
virtual char f(Param const &) const {return 'B';}
};
struct C : Base {
explicit C(Param const &) {}
virtual char f(Param const &) const {return 'C';}
};
char my_function(Param const & param, Base const & base)
{
if(A const * const p = dynamic_cast<A const *>(&base)) {
return p->f(param);
}
if(B const * const p = dynamic_cast<B const *>(&base)) {
return p->f(param);
}
if(C const * const p = dynamic_cast<C const *>(&base)) {
return p->f(param);
}
return '0';
}
然后如果我写
Param x, y;
std::cout << my_function(x, B(y)) << std::endl;
它输出B
。
我的目标是更改my_function
的实现,以便它可以支持在编译时定义的一组子类型Base
。在这里,我手写了我将为{A, B, C}
类型获得的扩展代码。 我想模板化my_function
有一组类型,并调用它是这样的:
std::cout << my_function<boost::mpl::set<A, B, C> >(x, B(y)) << std::endl;
输出B
,或者,如:
std::cout << my_function<boost::mpl::set<A, C> >(x, B(y)) << std::endl;
输出0
。
我不知道使用哪个MPL构造来实现此结果。
我最初以为find_if
一个电话可以让找到集合到base
可以dynamic_casted第一类,但实际上这个算法,最喜欢的MPL算法,静态显然产生了效果,因此不能与运行时参数一起使用(base
)。
分类为“运行时”的唯一MPL算法是for_each
,但我无法弄清楚如何使用它来产生与我的多重返回语句相同的效果(我甚至不知道它是否是它是可能的)。 感谢任何能帮助我的MPL演讲者。
PS:不要告诉我,我应该避免动态蒙上或我可以简单地
char my_function(Param const & param, Base const & base) {return base.f(param);}
我简单跟我现实生活中的问题相比,代码示例,我不能改变现有的设计。
谢谢你的回答。您的解决方案的缺点是每次都会遍历整个类型列表,但它很好地展示了如何使用MPL for_each。同时,我找到了我发布的解决方案(不使用MPL算法)。 –