Never underestimate Generic Lambda in Modern C++

This is an update of my previous post. With a moral to the story too.  I might hope some C++ beginner might learn something useful here too.

[On-line source code is here]

 

Having my usual morning workout in the brain gym called cppreference.com, I noticed a comment inside the example snippet on the page  about std::apply

Hmm, says I: why is this? add_generic() in that example looks fairly generic and simple to me.

Ok then. A quick copy and paste into my Visual Studio 2017.

Few variations later I indeed concluded template arguments of the add_generic() cannot be deduced.  So let me try with generic lambda.

And it worketh. Nice and simple, generic modern standard C++ code.

Why is a generic lambda working where generic template function does not? Well, there is an explanation and it is rather obvious. Which makes it difficult to spot immediately.

The C++ template is just that: a template. An empty vessel waiting to be instantiated with its arguments.

This is a template (function) :

Thus ‘template_adder’ is as close to nothing as you can get… it is just a template name.  Its instance, on the other hand, is everything, it has a type. It exists.

Above are two types made to exist by instantiating a template.  For a compiler, a template is “nothing”, just a declaration, and its instance, or definition, is “everything”.  Unused templates are simply removed by a compiler.

So, the std::apply requires a callable object as its first argument. And the template is not any kind of object, and template function instance (aka definition) is the function one can use by calling it. That object is Callable, and that is what std::apply needs as the first argument. The first argument can not be a template name, it has to be a template definition if the callable object is a template.

That works but requires providing the types to the adder and thus removes all the magic from the code using the generic lambdas.

Now consider using this in a situation where the two types to be added are not obvious fundamental types. Lambda-based solution will be unchanged

as long as there is ‘+’ operator that can ‘add’ the a and b above the lambda based solution is unchanged.

Now how would one do this for the template function which needs to be a specific definition required to add two arbitrary values of two arbitrary types? Perhaps something like:

Hm … even less magic here.

I think I might suggest, just use generic lambda and leave it to your shiny modern C++ compiler to sort it out and generate the right kind of code.

Meanwhile. Back at  cppreference.com HQ, and not long after, my improvement was adopted and the example code changed accordingly.  It is nice to communicate with nice people behind ccpreference.com.

That was one good C+++ morning indeed.

 

 

So little C++ so much good!
So little C++ so much good!

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.