在运行时选择相同功能的版本

时间:2016-07-13 03:36:32

标签: c++ switch-statement

我目前正在开发一个项目,每次程序运行时都可以调用同一算法的4个版本之一(涉及不同的并行编程框架及其顺序类似)。

所有这些4的参数是相同的,并行框架细节将在函数本身内处理。

我是C ++的新手,所以不知道是否可以更改function()指向的代码,并根据命令行选择正确的版本参数。

警告:隐藏的伪代码:

switch(version){
    case OMP:
        // make function() point to 1st version
    case CUDA:
        // ... to function2()
    case OCL:
        // ... to function3()
    case SEQ:
    default:
        // ... to function0()
}

// ...

while(condition){
    // call function()
}

所以我试图找出一种优雅的方法,在不同的文件中使用不同的算法,只需在主程序中处理I / O.一些行为模式?

3 个答案:

答案 0 :(得分:4)

如果您有简单的功能而且不需要类层次结构,则可以使用std::function

std::function<void (int, float)> target;

switch(version){
    case OMP: target = function1; break;
    case CUDA: target = std::bind(function2, "hello", _1, _2); break;
    case OCL: target = function3; break;
    case SEQ: target = function4; break;
    default: target = function0; break;
}

target(100, 3.14);

答案 1 :(得分:1)

这是Strategy pattern的典型示例。策略模式的基本思想是,您将拥有一个抽象的Strategy,它将具有纯虚拟executerun方法。每种不同的算法或策略都会有具体的子类。

对于您的情况,大纲可以是这样的:

class BaseStrategy {
    virtual void execute(params...) = 0;
}

class OMPStrategy : public BaseStrategy {
    // implement execute method for OMP
}

class CUDAStrategy : public BaseStrategy {
    // implement execute method for CUDA
}

// etc

现在,在您需要选择一个版本的方法中,您将根据您的输入实例化正确的策略对象,并在其上调用execute

这样的事情:

BaseStrategy *strategy;

switch(version){
    case OMP:
        strategy = new OMPStrategy();
        break;
    case CUDA:
        strategy = new CUDAStrategy();
        break;
    case OCL:
        strategy = new OCLStrategy();
        break;
    case SEQ:
        strategy = new SEQStrategy();
        break;
    default:
        strategy = new DefaultStrategy();
}

// now call it

while(condition){
    strategy->execute();
}

// delete strategy when done
delete strategy;

通过这种方式,您可以在不同的类中实现不同算法的清晰单独实现。

注意:正如注释中所指出的,如果抛出异常,可能会发生内存泄漏。如果您使用的是c ++ 11,那么使用std::shared_ptrstd::unique_ptr将比使用原始指针更好。

答案 2 :(得分:1)

如果您使用的是Linux(可能还有其他Unix),可以在运行时使用dlopen()加载正确的库函数,请参阅&#39; man 3 dlopen&#39;。

dlopen系列在您拥有主应用程序并且希望能够使用例如热补丁进行热补丁的情况下也很有用。一个较新版本的插件库。原则上,甚至不必重新启动主应用程序来升级插件。

自从我在Windows中入侵以来已经有一段时间了,但是在Windows和Mac中也存在类似于dlopen的可能性。 (Mac基于BSD变体,所以即使dlopen()也可以工作)。