首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >自动类型推导并将lambda传递给std::function参数

自动类型推导并将lambda传递给std::function参数
EN

Stack Overflow用户
提问于 2017-01-20 12:45:27
回答 3查看 705关注 0票数 2

让我们假设我有一个具有以下签名的函数:

代码语言:javascript
复制
void foo(std::function<void(int&)>& bar);

以下调用成功编译:

代码语言:javascript
复制
foo([](int& x) { ++x; });

这也成功地编译了:

代码语言:javascript
复制
std::function<void(int&)> myFunction = [](int& x) { ++x; };
foo(myFunction);

但是,通过自动类型推断,它突然无法编译:

代码语言:javascript
复制
auto myFunction = [](int& x) { ++x; };
foo(myFunction);

AFAIK导出的lambda类型未指定,但它被认为是一个函子/可调用函数。我不明白的是,如果不允许将相同类型的std::function<void(int&)>作为函数参数传递,那么如何才能将相同的lambda分配给呢?

-std=c++11在GCC v4.8.5上进行测试。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2017-01-20 12:54:10

鉴于本案;

代码语言:javascript
复制
std::function<void(int&)> myFunction = [](int& x) { ++x; };
foo(myFunction);

转换发生,结果存储在命名对象myFunction中。反过来,命名对象可以绑定到foo所需的引用。

考虑到另外两起案件;

代码语言:javascript
复制
foo([](int& x) { ++x; });
// and
auto myFunction = [](int& x) { ++x; };
foo(myFunction);

从命名对象myFunction (在第二种情况下)到std::function的转换可以进行(在这两种情况下);但是会产生一个临时的。临时不能绑定到std::function引用,这是foo所需的,因此出现错误。添加一个const,如下所示,允许编译代码;

代码语言:javascript
复制
void foo(std::function<void(int&)> const& bar);

临时人员可以绑定到const引用。

样本代码

票数 5
EN

Stack Overflow用户

发布于 2017-01-20 12:55:55

以下调用成功编译: foo(int& x { ++x;});

错了,它不编译。原因是不能将临时的引用绑定到引用。

出于同样的原因:

代码语言:javascript
复制
auto myFunction = [](int& x) { ++x; };
foo(myFunction);

也不编译。myFunction类型是lambda的一种类型,因此创建了临时类型,将其传递给foo,因为foo希望std::function<void(int&)>&myFunction必须隐式转换为std::function<void(int&)>

在此:

代码语言:javascript
复制
std::function<void(int&)> myFunction = [](int& x) { ++x; };
foo(myFunction);

不创建临时的。所以代码编译成功。

票数 2
EN

Stack Overflow用户

发布于 2017-01-20 14:51:22

引用与值不相同。

代码语言:javascript
复制
std::function<void(int&)>&

这是一个参考资料。

代码语言:javascript
复制
std::function<void(int&)>

这是一个价值。

代码语言:javascript
复制
int&

这是一个参考资料。

代码语言:javascript
复制
int

这是一个价值。

代码语言:javascript
复制
int x = 3.0;

上面的方法很有效。

代码语言:javascript
复制
int& x = 3.0;

上面的话不起作用。

代码语言:javascript
复制
std::function<void(int&)> f = [](int&x){++x;};

上面的方法很有效。

代码语言:javascript
复制
std::function<void(int&)>& f = [](int&x){++x;};

上面的话不起作用。

代码语言:javascript
复制
void foo(std::function<void(int&)>& bar);

foo引用一个std::function。这意味着需要传递一个实际的std::function,而不是可转换到它的东西。

代码语言:javascript
复制
void foo2(std::function<void(int&)> const& bar);

foo2const&转换为std::function。在这里,你可以把一些可转换的东西传递给std::function

代码语言:javascript
复制
void foo3(std::function<void(int&)> bar);

foo3按值获取std::function。在这里,您可以将一些可转换的东西传递给std::function

lambda不是std::function,但只要签名兼容,它就可以转换为可转换的。因此,这类似于“将double传递给int”的情况,在这种情况下,double将-转换为int,但不能将int&转换为double

C++允许临时const&,但不允许&,因为&意味着您打算更改它,并且这些更改不会在临时的过程中传播。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41764035

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档