Lambda闭包左值可以作为右值参考参数传递
Lambda closure lvalues can be passed as rvalue reference parameters
我发现lvalue
lambda闭包总是可以作为rvalue
函数参数传递。
请参阅以下简单演示。
#include <iostream>
#include <functional>
using namespace std;
void foo(std::function<void()>&& t)
{
}
int main()
{
// Case 1: passing a `lvalue` closure
auto fn1 = []{};
foo(fn1); // works
// Case 2: passing a `lvalue` function object
std::function<void()> fn2 = []{};
foo(fn2); // compile error
return 0;
}
情况2是标准行为(我只是使用std::function
进行演示,但任何其他类型的行为都是一样的(。
案例1是如何运作的,为什么运作?函数返回后,fn1
闭包的状态是什么?
std::function
。引用不会直接绑定。
情况1之所以有效,是因为lambda可以转换为std::function
s。这意味着临时std::function
通过复制fn1
来具体化。所述临时参数能够绑定到右值引用,因此参数与参数匹配。
复制也是fn1
完全不受foo
中发生的任何事情影响的原因。
案例1如何以及为什么工作?
调用foo
需要一个绑定到右值引用的std::function<void()>
实例。std::function<void()>
可以由与void()
签名兼容的任何可调用对象构造。
首先,从[]{}
构造一个临时的std::function<void()>
对象。这里使用的构造函数是#5,它将闭包复制到std::function
实例中:
template< class F > function( F f );
使用
std::move(f)
初始化目标。如果f
是指向函数的空指针或指向成员的空指针,则调用后*this
将为空。
然后,将临时function
实例绑定到右值引用。
函数返回后fn1闭包的状态是什么?
与以前相同,因为它已复制到std::function
实例中。原始闭合不受影响。
函数返回后,fn1闭包的状态是什么?
fn1
是无状态的,因为它不捕获任何内容。
案例1是如何工作的,为什么工作?
它之所以有效,是因为参数的类型与被右值引用的类型不同。由于具有不同的类型,因此会考虑隐式转换。由于lambda对于此std::function
的参数是可调用的,因此它可以通过std::function
的模板转换构造函数隐式转换为它。转换的结果是一个prvalue,因此可以与右值引用绑定。
- 通用参考 l 值不复制对象
- 是否有必要使用 std::move?这不是已经是一个右值参考了吗?
- Lambda闭包左值可以作为右值参考参数传递
- 如何获取地图值的参考?
- 演绎指南中的参考文献和值之间的差异
- 赋值运算符的返回值可以作为参考吗?
- 如果值来自成员变量,则复制初始化和参考初始化之间的C 差异
- 超载函数既不按值,也不是通过参考来对象,而是将撤销的指针换成对象
- 移动 l 值参考参数是否是一种不好的做法?
- C 按值返回与参考返回
- 为什么未调用具有常量参考返回值的超载方法
- 是否有一种方法可以始终通过值(制作副本)而不是在使用类成员函数时通过参考来传递
- 作为RVALUE参考与双移动值的传递
- 可以std ::移动引起切片时切入L值参考
- 为什么通用参考和右值参考的流量不同
- 提供功能版本,其中可用值和参考
- 通过值和参考,对象构建返回对象之间的区别
- 按值传递参考参数
- C 模板函数基于参数是值还是参考
- 使用具有默认值的参考参数是一种良好的做法