The standard approach here is to separate the selection of a type from the use of the type: the latter takes the form of a function template instantiated several times by the former non-template function (or function template with fewer template parameters).
To avoid duplicating the normal parameters between these two layers, use a generic lambda as the template. To avoid duplicating the selection logic, make a function template that calls whatever lambda with the appropriate policy:
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);
}