C++ 自动类型推断并将lambda传递给std::function参数
假设我有一个具有以下签名的函数:C++ 自动类型推断并将lambda传递给std::function参数,c++,c++11,lambda,C++,C++11,Lambda,假设我有一个具有以下签名的函数: void foo(std::function<void(int&)>& bar); 这也成功地编译了: std::function<void(int&)> myFunction = [](int& x) { ++x; }; foo(myFunction); AFAIK推导出的lambda类型未指定,但它应该充当函子/可调用函数。我不明白的是,如果不允许将同一lambda作为同一类型的函数参数传递,那么如
void foo(std::function<void(int&)>& bar);
这也成功地编译了:
std::function<void(int&)> myFunction = [](int& x) { ++x; };
foo(myFunction);
AFAIK推导出的lambda类型未指定,但它应该充当函子/可调用函数。我不明白的是,如果不允许将同一lambda作为同一类型的函数参数传递,那么如何将同一lambda分配给std::function
在GCC v4.8.5上测试,在这种情况下使用-std=c++11
std::function<void(int&)> myFunction = [](int& x) { ++x; };
foo(myFunction);
可以将命名对象myFunction
(在第二种情况下)转换为std::function
(在两种情况下);但一个暂时的结果产生了。临时变量无法绑定到foo
所需的std::function
引用,因此出现错误。添加一个const
,如下所示,可以编译代码
void foo(std::function<void(int&)> const& bar);
void foo(标准::函数const&bar);
允许临时变量绑定到const
引用
以下调用已成功编译:
foo([](int& x) { ++x; });
错了,是它。原因是您无法将临时文件绑定到引用
std::function<void(int&)>
int
出于同样的原因:
auto myFunction = [](int& x) { ++x; };
foo(myFunction);
也不编译。myFunction
的类型是lambda的一种类型,因此创建临时函数将其传递给foo
,因为foo
需要std::function&
并且myFunction
必须隐式转换为std::function
void foo3(std::function<void(int&)> bar);
在这里:
std::function myFunction=[](int&x){++x;};
foo(myFunction);
不创建临时文件。因此代码编译成功。引用与值不同
std::function<void(int&)>&
int&
int x = 3.0;
这是一个参考
std::function<void(int&)>
int
这是一个价值观
std::function<void(int&)>&
int&
int x = 3.0;
以上工作
int& x = 3.0;
std::function<void(int&)>& f = [](int&x){++x;};
上述方法不起作用
std::function<void(int&)> f = [](int&x){++x;};
void foo(std::function<void(int&)>& bar);
foo2
将const&
转换为std::function
。在这里,您可以将可转换的内容传递给std::function
void foo3(std::function<void(int&)> bar);
void foo3(标准::功能条);
foo3
按值获取std::function
。在这里,您可以将可转换的内容传递给std::function
void foo3(std::function<void(int&)> bar);
lambda不是std::function
,但只要签名兼容,它就可以转换为一个。因此,其行为类似于“将double
传递给int
”情况,其中double
转换为int
,但无法将int&
转换为double
C++允许对临时变量使用
常量&
,但不允许&
,因为&
意味着您打算更改它,并且更改不会通过临时变量传播。如果缺少常量
,则所有变量都可以正常编译()。但是,如果没有第二个代码段(正如我所期望的那样),您的第一个示例就可以编译了???它没有,或者是的,在其他答案提到代码不应该编译之后,我在cpp.sh和godbolt上都检查过(在那里使用gcc v4.8.5),它确实没有编译。奇怪,因为在我的工作机器上,gcc编译它没有问题,现在我得到了解释如何只能将右值绑定到常量引用的答案。。。