简体   繁体   中英

Why are C++20 template lambdas using typename keyword?

I understand the consistency argument, but most of the parameters for templates are types so I feel that since lambdas are meant to be concise way of defining a struct it probably should have been defaulted to typename / class (you would still need to write int/size_t/short ).

If somebody is not familiar with changes to lambdas in C++20 here is the example:

[]<typename T>(const std::vector<T>& v)
{
    for(const auto& x : v) { std::cout << x; }
};

and my question is why not:

[]<T>(const std::vector<T>& v)
{
    for(const auto& x : v) { std::cout << x; }
};

The problem is that this already has a meaning:

template <T> void foo();

It's a function template with one template parameter that is a non-type template parameter whose type is T , and that template parameter has no name.

It would be pretty confusing if the same syntax meant very different things depending on if you're introducing a function template or a generic lambda -- which is to say, two very similar contexts serving similar purposes!

Plus then... what would you do if you actually want a non-type template parameter? Just can't have one?

While conciseness is indeed a selling point of lambdas, it is not important enough to supersede the need for consistency. This is especially true for features involving templates, as they are harder to grasp than non-template language features.

In particular, the template syntax for generic lambdas has a narrow scope in the first place, ie, most lambdas can live without it (in fact, the example you gave is a perfect example of not to use it as the function body doesn't instantiate a T or does something comparable). From P0428 (emphasis mine):

There are a few key reasons why the current syntax for defining generic lambdas is deemed insufficientby the author. The gist of it is that some things that can be done easily with normal functiontemplates require significant hoop jumping to be done with generic lambdas, or can't be done at all.

Generic lambdas with decltype usage in their body are likely to be the most prominent clients of the new features. And replacing the decltype / decay_t -trickery with <typename T> seems more acceptable to me in terms of additional typing and conciseness.

If you simply write

[]<T>(){ }

what is T ?

A typename ? An auto value?

It seems to me that, in lambdas as in common functions, it's necessary explicit what is a template argument.

And if you can deduce that T is a type from the use (if it's used as first template argument for std::vector must be a type) why simplify only lambda syntax and not also the syntax of traditional template functions?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM