调用基类方法使用std::function

huangapple go评论79阅读模式
英文:

Calling base class method with std::function

问题

我在基本类虚方法中使用了std::function,结果出现了奇怪的问题。然后我调用了std::function对象,却调用了派生(而不是基本)方法。请问,你能告诉我问题出在哪里吗?

#include <functional>
#include <iostream>
#include <string>

struct A
{
    virtual void username(const std::string& name)
    {
        std::cout << "A: username" << name << '\n';
    }

    A* A_ptr()
    {
        return this;
    }
};

struct B : public A
{
    void username(const std::string& name) override
    {
        std::function<void(const std::string&)> f = std::bind(&A::username, A::A_ptr(), std::placeholders::_1);
        wrapper(f, name);
    }

    void wrapper(const std::function<void(const std::string&)>& f, const std::string& s)
    {
        f(s);
    }
};

int main()
{
    B b;
    b.username("tname");
}

注意:这段代码中的问题在于std::function的绑定,在B类中的username方法中,它绑定了基类Ausername方法,导致了派生类Busername方法无法被正确调用。

英文:

I used std::function for basic class virtual method and had strange result. Then I call std::function object, derived (not basic) method is called. Please, can you tell me there is the problem?

#include &lt;functional&gt;
#include &lt;iostream&gt;
#include &lt;string&gt;

struct A
{
    virtual void username(const std::string&amp; name)
    {
        std::cout &lt;&lt; &quot;A: username&quot; &lt;&lt; name &lt;&lt; &#39;\n&#39;;
    }

    A* A_ptr()
    {
        return this;
    }
};

struct B : public A
{
    void username(const std::string&amp; name) override
    {
        std::function&lt;void(const std::string&amp;)&gt; f = std::bind(&amp;A::username, A::A_ptr(), std::placeholders::_1);
        wrapper(f, name);
    }

    void wrapper(const std::function&lt;void(const std::string&amp;)&gt;&amp; f, const std::string&amp; s)
    {
        f(s);
    }
};

int main()
{
    B b;
    b.username(&quot;tname&quot;);
}

答案1

得分: 2

我不认为使用 std::bind 是可能的,但你可以使用 lambda 表达式来实现:

std::function<void(const std::string&)> f = [this](const std::string& name) {
  A::username(name);
};

默认情况下,对虚拟方法的成员函数指针将使用虚拟分发,要调用基类方法,你需要使用不同的语法,这在使用 std::bind 时不可能实现。

英文:

I don't think is is possible with std::bind, you can do it with a lambda though:

std::function&lt;void(const std::string&amp;)&gt; f = [this](const std::string&amp; name) {
  A::username(name);
};

By default a member function pointer to a virtual method will use virtual dispatch, to call the base class method you need to use a different syntax which isn't possible though std::bind

huangapple
  • 本文由 发表于 2023年7月11日 15:03:02
  • 转载请务必保留本文链接:https://go.coder-hub.com/76659420.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定