看一下下面列出的代码示例,我使用编译器资源管理器(使用 gcc 和 clang)对其进行了测试,它可以工作并打印出 200 的(预期)输出。
我想弄清楚的是:为什么这个 C++ 是有效的。或者不是吗?
在这里,我使用关键字为 function typeusing定义别名(而不是 a ) ,它描述了采用 an作为参数并返回 an (是函数类型,而不是函数指针类型!)的函数。等效语法是. 由于 C++ 标准规定,每个函数都有一个使用该语法的等效形式,因此很明显,这是指定此函数类型的明确定义的方法。typedefftintintfttypedeftypedef int ft(int);typedefusingusing ft = int(int)
现在有趣的部分来了:我使用类型ft来指定另一个函数 () 的参数类型print_it,然后调用它,传递一个 lambda 函数。我的问题是:C++ 标准在哪里/如何说这实际上应该起作用?我认为这是传递 lambda 的一种非常简单的方法。我不清楚这是否有效,因为 lambda 实际上是一个函子,而不是严格意义上的函数。所以我认为尚不清楚这个 lambda 是否与类型匹配ft,因此可以传递给print_it(如果ft被定义为是的话std::function<int(int)>,那就很清楚了)。
代码示例:
#include <iostream>
using ft = int(int);
void print_it (ft f, int a)
{
std::cout << f(a) << std::endl;
}
int main ()
{
auto my_lambda = [] (int a) -> int { return 2 * a; };
print_it (my_lambda, 100);
return (0);
}
Run Code Online (Sandbox Code Playgroud)
我的问题是:C++ 标准在哪里/如何说这实际上应该起作用?
这是在[expr.prim.lambda.closure]/7中指定的,它指定 lambda 的闭包类型有一个转换函数,转换为与 lambda 的参数和返回类型匹配的函数指针类型(如果 lambda 是非泛型且不存在)有任何捕获。通过此函数指针进行调用的行为基本上就好像 lambda 主体只是指针所指向的普通函数一样,这是可能的,因为没有捕获可以为 lambda 提供普通函数无法拥有的状态。
这适用于此处,并且您在将 lambda 对象传递给 时使用转换运算符将 lambda 对象隐式转换为函数指针print_it。这是有效的,因为 lambda 的参数和返回类型与ft类型匹配,并且用作函数参数类型的函数类型被调整为函数指针类型。(最后一部分请参阅[dcl.fct]/5 。)
对于泛型 lambda,有一个转换函数模板(请参阅以下标准段落)。对于带有捕获的 lambda,没有这样的转换函数,因此这对它们不起作用。
| 归档时间: |
|
| 查看次数: |
169 次 |
| 最近记录: |