运行时的不同执行策略

Bas*_*sti 6 c++ parallel-processing

在C++ 17中,algorithm标题中的许多函数现在可以采用执行策略.我可以举例来定义和调用这样的函数:

template <class ExecutionPolicy>
void f1(const std::vector<std::string>& vec, const std::string& elem, ExecutionPolicy&& policy) {
    const auto it = std::find(
        std::forward<ExecutionPolicy>(policy),
        vec.cbegin(), vec.cend(), elem
    );
}

std::vector<std::string> vec;
f1(vec, "test", std::execution::seq);
Run Code Online (Sandbox Code Playgroud)

但是我没有找到在运行时使用不同策略的好方法.例如,当我想根据某些输入文件使用不同的策略时.

我玩弄变种,但最后问题总是不同的类型std::execution::seq,std::execution::par和std::execution::par_unseq.

一个工作但繁琐的解决方案看起来像这样:

void f2(const std::vector<std::string>& vec, const std::string& elem, const int policy) {
    const auto it = [&]() {
        if (policy == 0) {
            return std::find(
                std::execution::seq,
                vec.cbegin(), vec.cend(), elem
            );
        }
        else if (policy == 1) {
            return std::find(
                std::execution::par,
                vec.cbegin(), vec.cend(), elem
            );
        }
        else{
            return std::find(
                std::execution::par_unseq,
                vec.cbegin(), vec.cend(), elem
            );
        }
    };
}

f2(vec, "test", 0);
Run Code Online (Sandbox Code Playgroud)

我有什么更优雅的解决方案吗?

编辑:也许我应该更精确.假设目标是将策略保存在可以具有三种策略之一的变量中.该变量应该是函数的参数.

Dav*_*ing 8

这里的标准方法是将类型的选择与类型的使用分开:后者采用由前者的非模板函数(或模板参数较少的函数模板)多次实例化的函数模板的形式。

为避免在这两层之间复制普通参数,请使用通用 lambda 作为模板。为避免重复选择逻辑,请创建一个函数模板,使用适当的策略调用任何 lambda:

enum Policy {seq,par,par_unseq};

template<class F>
auto maybe_parallel(F f,Policy p) {
  switch(p) {
  case seq: return f(std::execution::seq);
  case par: return f(std::execution::par);
  default: return f(std::execution::par_unseq);
  }
}

auto f2(const std::vector<std::string>& vec,
        const std::string& elem,Policy p) {
  return maybe_parallel
    ([&](auto &pol) {return std::find(pol,vec.begin(),vec.end(),elem);},p);
}
Run Code Online (Sandbox Code Playgroud)