通用 lambda 的熟悉模板语法

2021-12-23 00:00:00 lambda language-lawyer c++ c++20

对于 c++20,建议为通用 lambdas 添加以下语法 p0428r2.pdf

For c++20 it is proposed to add the following syntax for generic lambdas p0428r2.pdf

auto f = []<typename T>( T t ) {};

但是当前在 gcc 8 中的实现不接受以下实例化:

But the current implementation in gcc 8 did not accept the following instantiation:

f<std::string>("");

这是 gcc 中的实现错误还是缺少语言功能?我知道我们谈论的是提案而不是批准的规范.

Is that a implementation bug in gcc or a missing language feature? I know we talk about a proposal and not a approved specification.

完整示例(与模板函数语法比较):

Complete example ( with comparison to template function syntax ):

template <typename T> void n( T t ) { std::cout << t << std::endl; }

auto f = []<typename T>( T t ) { std::cout << t << std::endl; };

int main()
{
    f<std::string>("Hello");  // error!
    n<std::string>("World");
}

抱怨以下错误:

main.cpp:25:22: 错误:'>' 标记前的预期主表达式f("你好");

main.cpp:25:22: error: expected primary-expression before '>' token f("Hello");

推荐答案

lambda 表达式的结果不是函数;它是一个函数对象.也就是说,它是一个具有 operator() 重载的类类型.所以这个:

The result of a lambda expression is not a function; it is a function object. That is, it is a class type that has an operator() overload on it. So this:

auto f = []<typename T>( T t ) {};

相当于:

struct unnamed
{
  template<typename T>
  void operator()(T t) {}
};

auto f = unnamed{};

如果你想显式地为 lambda 函数提供模板参数,你必须显式调用 operator():f.operator()