显式指定通用 lambda 的 operator() 模板参数是不是合法?
Posted
技术标签:
【中文标题】显式指定通用 lambda 的 operator() 模板参数是不是合法?【英文标题】: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 <class From, class To> constexpr To nightmare_cast(From t) return [](auto v)constexpr return v; .operator() < To > (t);
愿诸神原谅我:)
【参考方案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
,按出现顺序。 ...
【讨论】:
以上是关于显式指定通用 lambda 的 operator() 模板参数是不是合法?的主要内容,如果未能解决你的问题,请参考以下文章
从通用 lambda 调用 `this` 成员函数 - clang vs gcc
显式原子加载/存储与通常的 operator= 和 operator T 有啥区别?
operator== 和 boost::detail::atomic_count 中的显式构造函数?