[英]std::function vs auto call to different overload
我有以下代码:
#include <iostream>
#include <functional>
void f(const std::function<void()>&)
{
std::cout << "In f(const std::function<void()>&)." << std::endl;
}
void f(std::function<void()>&&)
{
std::cout << "In f(std::function<void()>&&)." << std::endl;
}
int main()
{
auto func = []() { std ::cout << "func\n"; };
f(func); // calls void f(std::function<void()>&&)
/*const*/ std::function<void()> func2 = []() { std ::cout << "func\n"; };
f(func2); // calls void f(const std::function<void()>&)
f([]() { std ::cout << "func\n"; }); // calls void f(std::function<void()>&&)
return 0;
}
我想知道为什么第一次调用f
(当我使用auto
和lambda函数时)调用void f(std::function<void()>&&)
重载而不是void f(const std::function<void()>&)
,当我将变量声明为( const
) std::function<void()>
时,由第二次调用f
调用。
对于第一种情况,即使用auto
, func
的类型是一个唯一的lambda闭包类型,它不是std::function<void()>
,但可以隐式转换为std::function
。
std :: function的实例可以存储,复制和调用任何Callable目标 - 函数,lambda表达式,绑定表达式或其他函数对象,以及指向成员函数和指向数据成员的指针。
在转换之后,我们将获得类型为std::function<void()>
rvalue,并且对rvalue的绑定rvalue-reference比在重载解析中绑定lvalue-reference到rvalue更好,然后调用第二个重载。
3)标准转换序列S1优于标准转换序列S2 if
c)或者,如果不是这样,S1和S2都将引用参数绑定到ref-qualified成员函数的隐式对象参数之外的其他内容,S1将rvalue引用绑定到rvalue,而S2绑定左值引用一个右值
对于func2
情况, func2
被声明为std::function<void()>
的确切类型,然后是f(func2);
不需要转换。 作为命名变量, func2
是一个左值,它不能绑定到rvalue-reference,然后调用第一个重载。
如果rvalue参数对应于非const左值引用参数或lvalue参数对应于rvalue引用参数,则该函数不可行。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.