std::函数与自动调用不同的重载
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 << "funcn"; };
f(func); // calls void f(std::function<void()>&&)
/*const*/ std::function<void()> func2 = []() { std ::cout << "funcn"; };
f(func2); // calls void f(const std::function<void()>&)
f([]() { std ::cout << "funcn"; }); // 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 的实例可以存储、复制和调用任何可调用目标 - 函数、lambda 表达式、绑定表达式或其他函数对象,以及指向成员函数的指针和指向数据成员的指针。
转换后,我们将得到一个类型std::function<void()>
的右值,并且在重载解析中将右值引用绑定到右值比将左值引用绑定到右值更好,然后调用第二个重载。
S1 优于标准转换序列 S2,如果
c) 或者,如果不是这样,S1 和 S2 都绑定到引用参数到引用限定成员函数的隐式对象参数以外的内容,并且 S1 将右值引用绑定到右值,而 S2 将左值引用绑定到右值
对于第二种情况,func2
被声明为std::function<void()>
的确切类型,那么对于f(func2);
则不需要转换。由于命名变量func2
是不能绑定到 rvalue-reference 的左值,因此将调用第一个重载。
非常量左值引用参数,或者左值参数对应于右值引用参数,则该函数不可行。
相关文章:
- 为什么我不能在 C++ 中的特定函数重载中调用同一函数的任何其他重载?
- 重载方法的方式会在使用临时调用时生成编译器错误
- 重载类方法的不明确调用
- C++ 如何重载 [] 运算符并进行函数调用
- 错误:无法解析对重载函数的引用;你的意思是调用它吗?
- 调用重载的"<大括号括起来的初始值设定项列表>"对于对来说就足够了是模棱两可的
- 为什么初始化时没有调用重载赋值运算符?
- 如何调用用于重载运算符"<<"的 friend 函数?
- 模板化类如何解析在其类型之一上调用的重载非成员函数?
- 为什么我的运算符 + 重载尽管是通过引用传递的,但仍调用我的复制构造函数?
- C++ 编译器错误:P1LinkedList.cpp:145:错误:重载的"to_string(int&)"调用不明确
- C++:对函子重载调用运算符的未定义引用
- 重载调用是不明确的:一对内联映射作为构造函数参数
- C++模板重载调用
- 使用子类型重载调用函数
- 从新重载调用构造函数和直接调用构造函数有什么区别?
- 使用已删除的副本构造函数和初始值设定项列表重载调用类定义中的成员构造函数
- 如何重载调用自身重载版本的函数
- 重载调用是二义性的
- C++运算符重载:调用默认函数