简体   繁体   English

std::bind 和 std::function 具有多态性,基数 class

[英]std::bind and std::function with polymorphism, base class

I'm trying to bind an object to a function, but the base's class function is being called.我正在尝试将 object 绑定到 function,但正在调用基地的 class function。 The code it's just an example for the real code.该代码只是真实代码的示例。 I will only have the string later in the real code.稍后我只会在实际代码中使用该字符串。

 class A {
    public:
        virtual void f(const std::string &s) {
            std::cout << "A " << s << std::endl;
        }
    };

    class B : public A {
    public:
        void f(const std::string &s) override {
            std::cout << "B " << s << std::endl;
        }
    };

    void main() {
        std::unique_ptr<A> a = std::make_unique<B>();

        std::function<void(const std::string &)> callback
                =  std::bind(&A::f, *a, std::placeholders::_1);
        callback("my string");
    }

The result is结果是

 A my string

I tried to change it to &B:f, but got an error.我试图将其更改为 &B:f,但出现错误。

No viable conversion from 'typename _Bind_helper<__is_socketlike<void (B::*)(const basic_string<char> &)>::value, void (B::*)(const basic_string<char> &), A &, const _Placeholder<1> &>::type' (aka '_Bind<void (Centerity::Cluster::Correlation::B::*(Centerity::Cluster::Correlation::A, std::_Placeholder<1>))(const std::basic_string<char> &)>') to 'std::function<void (const std::string &)>' (aka 'function<void (const basic_string<char> &)>')

I tried to change it to A* a = B();我试图将其更改为A* a = B(); same result.同样的结果。 Couldn't find a similar code anywhere.在任何地方都找不到类似的代码。 Of course creating B b will call B::f , but that's not helping me.当然,创建B b会调用B::f ,但这对我没有帮助。

I can lose the bind and use lambda, but I don't know how.我可以失去绑定并使用 lambda,但我不知道如何。

NOTE:笔记:

I don't know which compiler you are using but main shouldn't be void.我不知道您使用的是哪个编译器,但main不应该为空。 I have fixed it in my code below:我已经在下面的代码中修复了它:

#include <memory>
#include <iostream>
#include <functional>

class A {
public:
    virtual void f(const std::string &s)
    {
        std::cout << "A " << s << std::endl;
    }
};

class B: public A {
public:
    void f(const std::string &s) override 
    {
        std::cout << "B " << s << std::endl;
    }
};

int main() 
{
    std::unique_ptr<A> a = std::make_unique<B>();
    auto callback = std::bind(&A::f, a.get(), std::placeholders::_1);

    callback("my string");
    return 0;
}

Outputs:输出:

B my string

The catch is to pass pointer to the base class (pointing to an object of derived class) to std::bind(&A::f, a.get(), std::placeholders::_1);问题是将指向基 class 的指针(指向派生类的 object)传递给std::bind(&A::f, a.get(), std::placeholders::_1); . .

If you pass by value, then a new object of your base class A will be created (by copy constructor) and the f version of base class will be called as you have observed in your program.如果你按值传递,那么你的基 class A 的一个新的 object 将被创建(通过复制构造函数)并且基 class 的 f 版本将被调用,正如你在你的程序中观察到的那样。

As you ask for the lambda version:当您要求lambda版本时:

class A { 
    public:
        virtual void f(const std::string &s) {
            std::cout << "A " << s << std::endl;
        }   
};  

class B : public A { 
    public:
        void f(const std::string &s) override {
            std::cout << "B " << s << std::endl;
        }
};  

int main() {
    std::unique_ptr<A> a = std::make_unique<B>();

    auto callback = [&a](const std::string& s){ return a->f(s); };

    callback("my string");
}

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

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