考虑一堆基本类型,Foo
,所有这些都具有通用方法的独特实现,Bar()
。我可以结合Foo1
, Foo2
, Foo5
像这样:
CombinedFoo<Foo1, Foo2, Foo5> combined_foo;
它使用递归继承来使CombinedFoo
实际上等同于:
class CombinedFoo <Foo1, Foo2, Foo5>
{
Foo1 foo1;
Foo2 foo2;
Foo5 foo5;
public:
void Bar ()
{
foo1.Bar();
foo2.Bar();
foo5.Bar();
}
};
这很方便,但是当我想在运行时选择哪个时,我遇到了一个问题Foo
要组合(成单个对象)以发送到函数的类型,例如:
template <typename Foo> void Do (Foo && foo);
一个示例解决方案if
s and switch
s 解决 3 个选项版本:
int result = 0;
if (criteria_for_foo1)
result += 100;
if (criteria_for_foo2)
result += 10;
if (criteria_for_foo3)
result += 1;
switch (result)
{
case 001 : Do(Foo3());
break;
case 010 : Do(Foo2());
break;
case 011 : Do(CombinedFoo<Foo2, Foo3>());
break;
case 100 : Do(Foo1());
break;
case 101 : Do(CombinedFoo<Foo1, Foo3>());
break;
case 110 : Do(CombinedFoo<Foo1, Foo2>());
break;
case 111 : Do(CombinedFoo<Foo1, Foo2, Foo3>());
break;
default : break;
}
The if
报表很好,它们线性增长,但是switch
随着我们有更多的选择,声明呈指数级增长。我的现实世界问题有 4 个选项,因此我需要处理 16 个我不想维护的情况。
我相信没有办法避免可执行文件呈指数增长,但是有没有办法在 C++ 代码中避免这种情况(不会造成显着的低效率Bar
method)?或者对于这个一般问题是否有已知的解决方法/替代方案?
EDIT:
为了清楚起见:Do(Foo1); Do(Foo2)
不等于Do(CombinedFoo<Foo1, Foo2>())
,并且至关重要的是Foo
s 组合在一起进行一次调用Do
.
对于那些想知道现实世界动机的人:这是一个优化问题,我的Foo
真的是Generator
基本的sMove
可以编辑我的解决方案,然后将其发送到各种启发式方法中。如果我只送一份Generator
有时,我的求解器会重复相同类型的移动数千次,因此总是效率低下/陷入局部最小值(众所周知,重复考虑相同类型的移动会产生这种效果)。
我在运行时选择其中一些模板参数的原因是因为一些Move
s 不适用于某些问题实例(我的程序直到运行时才意识到)。