如何将重载的成员函数作为参数传递?

Wal*_*ari 4 c++ member-function-pointers class c++11 std-function

这是我面临的问题:我在一个类中有一个重载函数,并且我想将其重载之一作为参数传递。但是这样做时,出现以下错误:

"no suitable constructor exists to convert from <unknown-type> to std::function<...>"
Run Code Online (Sandbox Code Playgroud)

这是一个代码示例来说明这一点:

#include <functional>
#include <string>

class  Foo
{
private:
    int val1 , val2;
};    

class Bar
{
public:
    void function ( ) {
        //do stuff;
        Foo f;
        function ( f );
    }    
    void function ( const Foo& f ) {
        //do stuff
    }

private:
    //random attribute
    std::string str;    
};


void otherFunction ( std::function<void ( Bar& , const  Foo& ) > function ) {
    Bar b;
    Foo f;
    function(b,f);
}

int main ( ) {    
    otherFunction ( &Bar::function );
                    ^^^
                   error
}
Run Code Online (Sandbox Code Playgroud)

我了解编译器无法推断出要使用的重载,因此下一个最好的方法是static_cast,但是以下代码仍具有相同的错误

std::function<void ( Bar& , const Foo& )> f = static_cast< std::function<void ( Bar& , const Foo& )> > ( &Bar::function );
Run Code Online (Sandbox Code Playgroud)

And*_*hko 5

您需要转换为成员函数指针,而不是std::function

otherFunction ( static_cast<void(Bar::*)(const Foo&)>(&Bar::function) );
Run Code Online (Sandbox Code Playgroud)

生活

[编辑]

说明:

otherFunction ( &Bar::function );
Run Code Online (Sandbox Code Playgroud)

otherFunctionstd::function作为参数。std::function从函数指针(成员函数或自由函数,以及其他“可调用”类型,在这里无关紧要)具有隐式构造函数(隐式转换)。看起来像这样:

template< class F > 
function( F f );
Run Code Online (Sandbox Code Playgroud)
  • 这是一个模板参数
  • 虽然F是“可调用的”,但没有指定签名F

这意味着编译器不知道Bar::function您的意思,因为此构造函数对输入参数没有任何限制。这就是编译器所抱怨的。

你试过了

static_cast< std::function<void ( Bar& , const Foo& )> > ( &Bar::function );
Run Code Online (Sandbox Code Playgroud)

尽管看起来编译器具有此处需要的所有详细信息(签名),但实际上调用了相同的构造函数,因此没有任何有效的更改。(实际上,签名是不正确的,但即使是正确的签名也不起作用)

通过转换为函数指针,我们提供其签名

static_cast<void(Bar::*)(const Foo&)>(&Bar::function)
Run Code Online (Sandbox Code Playgroud)

这样就解决了歧义,因为只有一个这样的函数,编译器很高兴。