Вы можете устранить двусмысленность предиката самостоятельно, используя лямбда;
std::string
process_string(const std::string& str)
{
std::string result;
std::copy_if(str.begin(),
str.end(),
std::back_inserter(result),
[](char const& c) { return predicate(c); });
// ^^ use the lambda to call the correct overload
return result;
}
Также важно иметь в виду, что не шаблон будет предпочтительнее функции шаблона.
В качестве альтернативы вы можете использовать функцию указателя (но я считаю, что это более громоздко);
std::copy_if(str.begin(),
str.end(),
std::back_inserter(result),
static_cast<bool(*)(const char&)>(&predicate));
Demo.
Вариации приведения указателя включают в себя ввод типа указателя функции, а затем получение локальной переменной, указывающей на требуемую функцию;
using predicate_t = bool(*)(const char&);
predicate_t my_predicate = &predicate;
std::copy_if(str.begin(),
str.end(),
std::back_inserter(result),
my_predicate);
Demo.
По вопросу, какой вариант лучше, это зависит от сложности коды вне образца, их расположение (т.е. вашего кода против кода третьей стороны), объем неоднозначных ошибок, сам предикат ,
Учитывая простое условие, как в OP-коде, лямбда может содержать сам тест. В этом случае лямбда очень проста.
Если счетчик высок, версия using
в более высокой области (с локальной переменной для преобразования указателя) может быть подходящей.
Если это вопрос «один раз», то static_cast
будет также прекрасным. Хотя бросок выглядит «неуместным».
В конечном итоге это, вероятно, больше всего зависит от личных предпочтений (или рекомендаций, если у вас есть такие, которые охватывают эту ситуацию).
Лямбда также может быть объединена с более современным использованием auto&&
и некоторыми вариационными аргументами, as seen in this answer in the linked question. Стоит иметь в виду, что эти современные технологии хорошо согласуются. Большинство современных компиляторов также оптимизируют лямбда в этом случае, поэтому нет никаких затрат на его использование (это применимо ко всем вариантам здесь, там все просто устраняются двусмысленность).
В идеале на самом деле на самом деле не должно быть непоследовательности, но это происходит, и нам нужно иметь дело с ним наиболее подходящим способом, который мы можем в контексте, который мы находим.
Счетчик параметров. – knivil