【问题标题】:Is it legal to explicitly specify a generic lambda's operator() template arguments?显式指定通用 lambda 的 operator() 模板参数是否合法?
【发布时间】:2018-08-29 18:29:32
【问题描述】:

是否符合以下 C++ 代码标准?

#include <iostream>

int main()
{
    [](auto v){ std::cout << v << std::endl; }.operator()<int>(42);
}

clang++ 3.8.0 和 g++ 7.2.0 compile this code fine(编译器标志为 -std=c++14 -Wall -Wextra -Werror -pedantic-errors)。

【问题讨论】:

  • 如果你想查,这里有一份标准的here。
  • AFAIK 确实如此。 lambda 的 operator() 是公开的,所以我看不到任何可以阻止它的东西。
  • 阅读en.cppreference.com/w/cpp/language/lambda。你可以做到的。
  • 我知道您不必在language-lawyer 中给出原因,但出于好奇,您可能希望在哪种情况下给出原因?
  • @SergeyA, template &lt;class From, class To&gt; constexpr To nightmare_cast(From t) { return [](auto v)constexpr{ return v; }.operator() &lt; To &gt; (t); } 愿诸神原谅我:)

标签: c++ templates lambda language-lawyer generic-lambda


【解决方案1】:

这确实符合标准。该标准规定必须有一个成员operator(),并且在其参数声明子句中为auto 的每一次出现都有一个模板参数。没有任何措辞禁止明确提供这些内容。

底线:lambda 的调用运算符只是一个普通函数(模板,如果是通用的)。


供参考,相关标准条款:

非泛型 lambda 表达式的闭包类型有一个公共的 内联函数调用运算符(16.5.4),其参数和返回 类型由 lambda 表达式描述 parameter-declaration-clause 和 trailing-return-type 分别。 对于泛型 lambda,闭包类型具有公共内联函数 调用操作员成员模板 (17.5.2),其模板参数列表 由每个出现的一个发明类型模板参数组成 lambda 的参数声明子句中的 auto ,按顺序 外观。发明的类型模板参数是一个参数包 如果相应的参数声明声明了一个函数 参数包 (11.3.5)。返回类型和函数参数 函数调用运算符模板源自 lambda 表达式的尾随返回类型和 parameter-declaration-clause 通过替换每次出现的 auto in 带有名称的参数声明子句的声明说明符 相应发明的模板参数。

N4659 (C++17) 中的 8.1.5.1/3 [expr.prim.lambda.closure],强调我的。

【讨论】:

    【解决方案2】:

    是的,它似乎定义明确,因为 lambda 的 operator() 的模板参数是严格定义的。

    [expr.prim.lambda]/5

    ...
    对于泛型 lambda,闭包类型具有公共内联函数 调用操作员成员模板 (14.5.2),其 template-parameter-list 由一种发明类型 template-parameter 组成 对于 lambda 的 parameter-declaration-clause 中每次出现的 auto,按出现顺序。
    ...

    【讨论】:

      猜你喜欢
      • 2021-11-24
      • 1970-01-01
      • 2021-09-19
      • 1970-01-01
      • 2018-04-04
      • 2014-10-14
      • 2018-03-19
      • 2021-02-04
      相关资源
      最近更新 更多