std::function vs 自动调用不同的重载
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
.
Instances of std::function can store, copy, and invoke any Callable target -- functions, lambda expressions, bind expressions, or other function objects, as well as pointers to member functions and pointers to data members.
转换后我们将得到类型 std::function<void()>
的右值,将 rvalue-reference 绑定到右值比将 lvalue-reference 绑定到 overload resolution 中的右值更好,然后调用第二个重载。
3) A standard conversion sequence S1 is better than a standard conversion sequence S2 if
c) or, if not that, both S1 and S2 are binding to a reference parameter to something other than the implicit object parameter of a ref-qualified member function, and S1 binds an rvalue reference to an rvalue while S2 binds an lvalue reference to an rvalue
对于第二种情况,func2
被声明为 std::function<void()>
的确切类型,那么对于 f(func2);
则不需要转换。由于命名变量 func2
是一个左值,不能绑定到 rvalue-reference,因此调用第一个重载。
if an rvalue argument corresponds to non-const lvalue reference parameter or an lvalue argument corresponds to rvalue reference parameter, the function is not viable.
我有如下一段代码:
#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
.
Instances of std::function can store, copy, and invoke any Callable target -- functions, lambda expressions, bind expressions, or other function objects, as well as pointers to member functions and pointers to data members.
转换后我们将得到类型 std::function<void()>
的右值,将 rvalue-reference 绑定到右值比将 lvalue-reference 绑定到 overload resolution 中的右值更好,然后调用第二个重载。
3) A standard conversion sequence S1 is better than a standard conversion sequence S2 if
c) or, if not that, both S1 and S2 are binding to a reference parameter to something other than the implicit object parameter of a ref-qualified member function, and S1 binds an rvalue reference to an rvalue while S2 binds an lvalue reference to an rvalue
对于第二种情况,func2
被声明为 std::function<void()>
的确切类型,那么对于 f(func2);
则不需要转换。由于命名变量 func2
是一个左值,不能绑定到 rvalue-reference,因此调用第一个重载。
if an rvalue argument corresponds to non-const lvalue reference parameter or an lvalue argument corresponds to rvalue reference parameter, the function is not viable.