让我们假设我有一个具有以下签名的函数:
void foo(std::function<void(int&)>& bar);以下调用成功编译:
foo([](int& x) { ++x; });这也成功地编译了:
std::function<void(int&)> myFunction = [](int& x) { ++x; };
foo(myFunction);但是,通过自动类型推断,它突然无法编译:
auto myFunction = [](int& x) { ++x; };
foo(myFunction);AFAIK导出的lambda类型未指定,但它被认为是一个函子/可调用函数。我不明白的是,如果不允许将相同类型的std::function<void(int&)>作为函数参数传递,那么如何才能将相同的lambda分配给呢?
用-std=c++11在GCC v4.8.5上进行测试。
发布于 2017-01-20 12:54:10
鉴于本案;
std::function<void(int&)> myFunction = [](int& x) { ++x; };
foo(myFunction);转换发生,结果存储在命名对象myFunction中。反过来,命名对象可以绑定到foo所需的引用。
考虑到另外两起案件;
foo([](int& x) { ++x; });
// and
auto myFunction = [](int& x) { ++x; };
foo(myFunction);从命名对象myFunction (在第二种情况下)到std::function的转换可以进行(在这两种情况下);但是会产生一个临时的。临时不能绑定到std::function引用,这是foo所需的,因此出现错误。添加一个const,如下所示,允许编译代码;
void foo(std::function<void(int&)> const& bar);临时人员可以绑定到const引用。
样本代码。
发布于 2017-01-20 12:55:55
以下调用成功编译: foo(int& x { ++x;});
错了,它不编译。原因是不能将临时的引用绑定到引用。
出于同样的原因:
auto myFunction = [](int& x) { ++x; };
foo(myFunction);也不编译。myFunction类型是lambda的一种类型,因此创建了临时类型,将其传递给foo,因为foo希望std::function<void(int&)>&和myFunction必须隐式转换为std::function<void(int&)>。
在此:
std::function<void(int&)> myFunction = [](int& x) { ++x; };
foo(myFunction);不创建临时的。所以代码编译成功。
发布于 2017-01-20 14:51:22
引用与值不相同。
std::function<void(int&)>&这是一个参考资料。
std::function<void(int&)>这是一个价值。
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);foo引用一个std::function。这意味着需要传递一个实际的std::function,而不是可转换到它的东西。
void foo2(std::function<void(int&)> const& bar);foo2将const&转换为std::function。在这里,你可以把一些可转换的东西传递给std::function。
void foo3(std::function<void(int&)> bar);foo3按值获取std::function。在这里,您可以将一些可转换的东西传递给std::function。
lambda不是std::function,但只要签名兼容,它就可以转换为可转换的。因此,这类似于“将double传递给int”的情况,在这种情况下,double将-转换为int,但不能将int&转换为double。
C++允许临时const&,但不允许&,因为&意味着您打算更改它,并且这些更改不会在临时的过程中传播。
https://stackoverflow.com/questions/41764035
复制相似问题