Question

I can write a function template:

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

But in C++14, I can also create a generic lambda:

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

Within f1 I can refer to T directly. Within f2, there's no T to refer to, but I can get the same effect using decltype:

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

An advantage of the generic lambda is that I can perfect-forward it. I can't do that with the function template:

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

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

Are there situations where using a function template would be better than using a generic lambda?

Was it helpful?

Solution

Function templates permit overloading of other functions with the same name, and calling them works via ADL. Generic lambdas are objects with an overloaded (), so neither works.

You can pass a function overload set to an object pretty easily:

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

which with RVO can be optimized away completely (zero overhead), and an instance of the entire overload set can be passed to an algorithm. You can also do this with a lambda at point of use, which can be generated by a macro.

With a bit more boilerplate the above overload set can also support conversion to any call-compatible function pointer, which neither the template nor lambda solution supports (lambda requires signatures match one version, not compatibility).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top