Различные политики выполнения во время выполнения - PullRequest
0 голосов
/ 24 октября 2018

В 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);

Однако я не нашел хорошего способа использования различных политик во время выполнения.Например, когда я хочу использовать другую политику, зависящую от некоторого входного файла.

Я поиграл с вариантами, но в итоге проблема всегда была в различных типах std::execution::seq, std::execution::par и * 1009.*.

Рабочее, но громоздкое решение будет выглядеть так:

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);

Есть ли более элегантное решение, которое я упускаю из виду?

edit: может быть, мне следуетточнее.Допустим, цель состоит в том, чтобы сохранить политику в переменной, которая может иметь любую из трех политик.Эта переменная должна быть параметром функции.

1 Ответ

0 голосов
/ 26 октября 2018

Стандартный подход здесь состоит в том, чтобы отделить выбор типа от использования типа: последний принимает форму шаблона функции, несколько раз создаваемого первым-template function (или шаблон функции с меньшим количеством параметров шаблона).

Чтобы избежать дублирования нормальных параметров между этими двумя слоями, используйте общую лямбду в качестве шаблона.Чтобы избежать дублирования логики выбора, создайте шаблон функции, который вызывает любую лямбду с соответствующей политикой:

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);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...