3
#include <iostream>
#include <functional>

class Base
{
    public:
        virtual ~Base() {}
        virtual void f1() const {std::cout<<"Base::f1() called"<<std::endl;}
        virtual void f1(int) const {std::cout<<"Base::f1(int) called"<<std::endl;}
        virtual void f2() const {std::cout<<"Base::f2() called"<<std::endl;}
};

class Derived : public Base
{
    public:
        virtual ~Derived() {}
        void f1() const {std::cout<<"Derived::f1() called"<<std::endl;}
};

int main()
{
    Base base;
    Derived derived;
    auto func1 = std::bind(static_cast<void(Base::*)()const>(&Base::f1), std::cref(base));
    func1();
    auto func2 = std::bind(static_cast<void(Derived::*)()const>(&Derived::f1), std::cref(derived));
    func2();
    auto func3 = std::bind(&Base::f2, std::cref(base));
    func3();
    auto func4 = std::bind(&Derived::f2, std::cref(derived));
    func4();
    auto func5 = std::bind(static_cast<void(Base::*)(int)const>(&Base::f1), std::cref(base), std::placeholders::_1);
    func5(1);
    auto func6 = std::bind(static_cast<void(Derived::*)(int)const>(&Derived::f1), std::cref(derived), std::placeholders::_1);  // error line
    func6(2);
    return 0;
}

When I try to build above code, gcc gives following error message.

test.cpp:34:80: error: invalid static_cast from type ‘void (Derived::)() const’ to type ‘void (Derived::)(int) const’

auto func6 = std::bind(static_cast(&Derived::f1), std::cref(derived), std::placeholders::_1);

I'm wondering if there is any method with which I can bind Base::f1(int) via class Derived (bind func6 successfully here). Any help is appreciated.

qdtang
  • 31
  • 5
  • Did you mean to mark `Derived::f1` as `override`? – Tas Jul 25 '16 at 04:12
  • @Tas You don't need to write `override`. It implicitly overrides if there is a virtual function with the same signature in the base class. It's only to be *sure* that you override that you write `override`. – Rakete1111 Jul 25 '16 at 04:30
  • 1
    Adding `using Base::f1;` in `Derived` will work. Possible duplicate of [c++ issue with function overloading in an inherited class](http://stackoverflow.com/questions/14212190/c-issue-with-function-overloading-in-an-inherited-class) – neuront Jul 25 '16 at 04:34
  • 1
    @neuront This assumes that @qdtang is able to change the definition of `derived`. I voted to leave open since to me it seems like the question is about how to do it in the `bind` call. – anderas Jul 25 '16 at 05:44
  • @neuront Your solution does work. But I don't think my question is duplicated with the one you mentioned, since my methods are virtual. But [this thread](http://stackoverflow.com/questions/1896830/why-should-i-use-the-using-keyword-to-access-my-base-class-method) explains that even virtual function override will hide all the overloaded functions in the parent class, which solved my confusion. Thanks to all that commented – qdtang Jul 25 '16 at 06:56

1 Answers1

2

What about using &Derived::Base::f1 instead &Derived::f1 ?

I mean

auto func6 = std::bind(static_cast<void(Derived::*)(int)const>(&Derived::Base::f1), std::cref(derived), std::placeholders::_1); 

As suggested by Oktalist (thanks), you can also use &Base::f1.

It's even simpler.

Oktalist
  • 14,336
  • 3
  • 43
  • 63
max66
  • 65,235
  • 10
  • 71
  • 111
  • @Oktalist - you're right; thanks. Modified my answer. – max66 Jul 25 '16 at 19:14
  • Thanks for your post. This solution works fine as well. But my concern is that users (who do this binding) need to know more details about the class hierarchy to write like this. I think it is better using its own version of methods without user knowing the details. – qdtang Jul 26 '16 at 03:31