Когда использовать шаблон функции вместо общей лямбды?

Я могу написать шаблон функции:

template<typename T>
void f1(T parameter) { ... }

Но в C ++ 14 я также могу создать общую лямбду:

auto f2 = [](auto parameter) { ... };

В f1 Я могу сослаться на T непосредственно. В f2, нет никаких T ссылаться, но я могу получить тот же эффект, используя decltype:

auto f2 = [](auto parameter)
{
using T = decltype(param);
...
};

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

template<typename T>
void fwdToG(T&& param) { g(std::forward<T>(param)); }

fwdToG(f1);        // error!
fwdToG(f2);        // okay

Существуют ли ситуации, когда использование шаблона функции было бы лучше, чем использование общей лямбды?

7

Решение

функция templates разрешают перегрузку других функций с тем же именем, и вызов их работает через ADL. Общие лямбды — это объекты с перегруженными ()так что ни один не работает.

Вы можете передать объекту перегруженную функцию довольно легко:

 struct foo_overload_set_t {
template<class...Ts>
constexpr auto operator()(Ts&&...ts)const{ return foo(std::forward<Ts>(ts)...); }
};

который с помощью RVO может быть полностью оптимизирован (нулевые издержки), и экземпляр всего набора перегрузки может быть передан алгоритму. Вы также можете сделать это с помощью лямбды в точке использования, которая может быть сгенерирована макросом.

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

4

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]