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 时会调用它

对于第一种情况,即使用autofunc的类型是一个独特的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.