2

I want to create a std::function object for the parent class's version of a virtual and overridden function, see the following example:

#include <iostream>
#include <functional>

class Parent
{
    public:

        virtual void func1()
        {
            std::cout << "Parent::func1\n";
        }

        virtual void func2()
        {
            std::cout << "Parent::func2\n";
        }
};

class Child : public Parent
{
    public:

        // overrides Parent::func1
        virtual void func1()
        {
            std::cout << "Child::func1, ";
            Parent::func1();
        }

        // overrides Parent::func2
        virtual void func2()
        {
            std::cout << "Child::func2, ";
            std::function< void() > parent_func2 = std::bind( &Parent::func2, this );
            parent_func2();
        }
};

int main()
{
    Child child;

    child.func1(); // output: Child::func1, Parent::func1

    child.func2(); // output: Child::func2, Child::func2, ...

    return 0;
}

While the call to child.func1() behaves as expected, the call to child.func2() becomes an infinite recursion, where parent_func2() seems to call Child::func2() instead of Parent::func2() to which I intended to bind it.

Any idea how I can have parent_func2() really call Parent::func2?

  • 5
    I don't think you can do this directly, it will still only do a virtual dispatch. A better idea would be a lambda like `[=]{ this->Parent::func2(); }`. – Xeo Oct 08 '13 at 14:17
  • Why is Parent::func2 dispatched to Child::func2 in the call of std::bind and Parent::func1 isn't? Even though your workaround might work, I'd like to understand why this is so. – Sebastian Schneider Oct 08 '13 at 15:47
  • Because virtual dispatch is still done, it is only disabled with the explicit parent-function call, as far as I know. – Xeo Oct 08 '13 at 15:57

1 Answers1

0

You can do it by writing a small functor:

struct Parent_func2
{
  void operator()( Parent* p ) const
  {
    p->Parent::func2();
  }
};

And use

std::function< void() > parent_func2 = std::bind( Parent_func2(), this );

(thinking about it, I guess this is just a more verbose way of what Xeo suggested. @Xeo, make your comment an answer and you have my upvote...)

Daniel Frey
  • 55,810
  • 13
  • 122
  • 180