是否可以指定C ++ 20模板化的lambda来推断嵌套在参数中的类型?

NoS*_*tAl 1 c++ language-lawyer c++20

C ++ 20 lambdas获得了一项新功能(纸张p0428r2。),您可以将其指定<typename T>为正常功能。阅读该纸张时,我注意到一个示例:

auto f = []<typenameT>(std::vector<T> vector) { /* ... */ };
Run Code Online (Sandbox Code Playgroud)

那让我开始思考:

为什么语言不能“弄清楚” T是一种类型(因为std :: vector是一个模板,期望里面包含type参数<>)。

auto f = [](std::vector<T> vector) { /* T deduced ... */ };
Run Code Online (Sandbox Code Playgroud)

是否有技术上的限制来防止这种情况发生?使用案例是否太晦涩/稀少,以至于不能为其保证语言规则?

Bar*_*rry 7

是否有技术上的限制来防止这种情况发生?使用案例是否太晦涩/稀少,以至于不能为其保证语言规则?

是的,有一个技术限制可以阻止这种情况。该代码已经具有含义

struct T { int i; };
auto f = [](std::vector<T> vector) { /* T not actually deduced */ };
Run Code Online (Sandbox Code Playgroud)

模板与非模板有很大不同(有关详细信息,请参阅P1392)。之所以使用“简洁”语法concept auto x而不是仅仅拼写概念的原因之一concept x是因为许多人强烈希望基于所使用的名称类型,相同的语法不应该意味着完全不同的事物。

这种语言功能会导致相同的语法,这取决于是否找到该名称,从而导致含义迥异的事物-似乎很难理解代码。更糟糕的是,这会导致以下情况:作者的意图是该lambda实际上是一个模板,然后在某个时候,它只是通过偶然添加名称而变成了非模板,或者如果该名称被偶然引入了一个名为变量的变量(即int T;


为此,Concepts TS具有不同的语法,即:

auto f = [](std::vector<auto> vector) { /* deduced, but no name */ };
Run Code Online (Sandbox Code Playgroud)

似乎可能会为C ++ 23提出此Concepts TS功能,因为出于同样的原因,它肯定有用,因为我仍会[](auto x){}在许多地方而不是编写[]<class T>(T x){}