Я могу написать шаблон функции:
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
Существуют ли ситуации, когда использование шаблона функции было бы лучше, чем использование общей лямбды?
функция template
s разрешают перегрузку других функций с тем же именем, и вызов их работает через ADL. Общие лямбды — это объекты с перегруженными ()
так что ни один не работает.
Вы можете передать объекту перегруженную функцию довольно легко:
struct foo_overload_set_t {
template<class...Ts>
constexpr auto operator()(Ts&&...ts)const{ return foo(std::forward<Ts>(ts)...); }
};
который с помощью RVO может быть полностью оптимизирован (нулевые издержки), и экземпляр всего набора перегрузки может быть передан алгоритму. Вы также можете сделать это с помощью лямбды в точке использования, которая может быть сгенерирована макросом.
С немного большим количеством шаблонов вышеупомянутый набор перегрузки может также поддерживать преобразование в любой указатель на функцию, совместимую с вызовом, которая ни template
ни лямбда решение не поддерживает (лямбда требует подписи, совпадающие с одной версией, не совместимость).
Других решений пока нет …