为什么 C++20 模板 lambda 使用 typename 关键字?

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

我理解一致性论点,但模板的大部分参数都是类型,所以我觉得既然 lambda 是定义结构的简洁方式,它可能应该默认为 typename/class(你仍然需要写int/size_t/short)。

如果有人不熟悉 C++20 中对 lambda 的更改,请看这里的示例:

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

我的问题是为什么不:

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

如果你只是写

[]<T>(){ }

什么是T

一个typenameauto 值?

在我看来,在 lambda 中和在普通函数中一样,有必要明确什么是模板参数。

如果你能从使用中推断出 T 是一个类型(如果它被用作 std::vector 的第一个模板参数必须是一个类型)为什么只简化 lambda 语法而不是传统模板函数的语法?

虽然简洁确实是 lambda 的卖点,但它的重要性不足以取代对一致性的需求。对于涉及模板的功能尤其如此,因为它们比 non-template 语言功能更难掌握。

特别是,通用 lambda 的模板语法首先具有狭窄的范围,即大多数 lambda 都可以没有它(事实上,您给出的示例是不使用它的完美示例函数体不会实例化 T 或做类似的事情)。来自 P0428(强调我的):

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.

在其主体中使用 decltype 的通用 lambda 可能是新功能最突出的客户。用 <typename T> 替换 decltype/decay_t-trickery 在额外的打字和简洁方面对我来说似乎更容易接受。

问题是这个已经有一个意思:

template <T> void foo();

它是一个函数模板,有一个模板参数是一个non-type类型为T的模板参数,并且该模板参数没有名称。

如果相同的语法意味着 非常 不同的东西,这将非常混乱,这取决于您是引入函数模板还是通用 lambda —— 也就是说,两个非常相似的上下文服务于相似的目的!

然后...如果您真的想要一个 non-type 模板参数,您会怎么做?就不能有一个吗?