我有以下代码:

#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()>&),而当我将变量声明为(f)时,第二次调用const会调用它std::function<void()>

最佳答案

对于第一种情况,即使用autofunc的类型是唯一的lambda闭包类型,它不是std::function<void()>的类型,但可以隐式转换为 std::function



转换后,我们将得到一个类型为std::function<void()>的右值,并且将右值引用绑定(bind)到rvalue比在overload resolution中将左值引用绑定(bind)到rvalue更好,然后调用第二重载。



对于第二种情况,func2被声明为std::function<void()>的确切类型,然后对于f(func2);则无需进行转换。由于命名变量func2是一个左值,它不能绑定(bind)到右值引用,因此将调用第一个重载。

07-28 01:34
查看更多