简体   繁体   English

std :: function vs auto调用不同的重载

[英]std::function vs auto call to different overload

I have the following piece of code: 我有以下代码:

#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;
} 

I would like to know why the first call to f (when I use auto and the lambda function) calls the void f(std::function<void()>&&) overload and not the void f(const std::function<void()>&) , which is instead called by the second call to f when I declare the variable as a ( const ) std::function<void()> . 我想知道为什么第一次调用f (当我使用auto和lambda函数时)调用void f(std::function<void()>&&)重载而不是void f(const std::function<void()>&) ,当我将变量声明为( conststd::function<void()>时,由第二次调用f调用。

For the 1st case, ie with the usage of auto , the type of func is a unique lambda closure type, which is not of std::function<void()> , but could implicitly convert to std::function . 对于第一种情况,即使用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的实例可以存储,复制和调用任何Callable目标 - 函数,lambda表达式,绑定表达式或其他函数对象,以及指向成员函数和指向数据成员的指针。

After the conversion we'll get an rvalue of type std::function<void()> , and binding rvalue-reference to rvalue is better match than binding lvalue-reference to rvalue in overload resolution , then the 2nd overload is invoked. 在转换之后,我们将获得类型为std::function<void()> rvalue,并且对rvalue的绑定rvalue-reference比在重载解析中绑定lvalue-reference到rvalue更好,然后调用第二个重载。

3) A standard conversion sequence S1 is better than a standard conversion sequence S2 if 3)标准转换序列S1优于标准转换序列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 c)或者,如果不是这样,S1和S2都将引用参数绑定到ref-qualified成员函数的隐式对象参数之外的其他内容,S1将rvalue引用绑定到rvalue,而S2绑定左值引用一个右值

For the 2nd case, func2 is declared as the exact type of std::function<void()> , then for f(func2); 对于func2情况, func2被声明为std::function<void()>的确切类型,然后是f(func2); no conversion is required. 不需要转换。 As a named variable func2 is an lvalue, which can't be bound to rvalue-reference, then the 1st overload is invoked. 作为命名变量, 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. 如果rvalue参数对应于非const左值引用参数或lvalue参数对应于rvalue引用参数,则该函数不可行。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM