I have a base class with common behavior and derived classes with override virtual functions. But if tried to save the function pointer as std::vector
I will get the error:
ISO C++ forbids taking the address of an unqualified or
parenthesized non-static member function to form a pointer to member function.
I need something like this:
class Base
{
public:
virtual int fun1(int inp) = 0;
virtual int fun2(int inp) = 0;
int init(int inp, std::vector<std::function<int(int)>> Callbacks, int index)
{
if (index == 0)
return Callbacks[0](inp);
else
return Callbacks[1](inp);
}
int run()
{
return init(5, { &fun1, &fun2 }, 0);
}
};
class A : public Base
{
int fun1(int inp)
{
return inp * 10;
}
int fun1(int inp)
{
return inp * 100;
}
};
class B : public Base
{
int fun1(int inp)
{
return inp * 20;
}
int fun2(int inp)
{
return inp * 200;
}
};
int main(int argc, char const* argv[])
{
auto f = new B;
int e = f->run();
return 0;
}
Is there any way to do what I want? Maybe I can bind a virtual function to a container somehow? Or maybe can I set the lambda function as virtual? When I tried to declare lambda function in the Base
class when I change function in derived class I get errors:
You get a "pointer" to a member with the syntax &Class::Member
(Class::Member
is the "qualified" name of the member).
These are pointers only in an abstract sense, and need to be dereferenced relative to an object.
You do this with the ->*
or .*
operator, depending on whether the left-hand side is a pointer or not.
Note that you must use this
explicitly, if that is the relevant object.
The type of &Base::fun1
and &Base::fun2
is int (Base::*)(int)
, which can't be converted to std::function<int(int)>
.
Putting it together:
int init(int inp, std::vector<int (Base::*)(int)> Callbacks, int index)
{
if (index == 0)
return (this->*Callbacks[0])(inp); // The leftmost parentheses are necessary.
else
return (this->*Callbacks[1])(inp);
}
int run()
{
return init(5, {&Base::fun1, &Base::fun2}, 0);
}
If you don't want to limit the callbacks to members, you can use lambda functions, capturing this
:
int init(int inp, std::vector<std::function<int(int))> Callbacks, int index)
{
if (index == 0)
return Callbacks[0](inp);
else
return Callbacks[1](inp);
}
int run()
{
return init(5,
{[this](int i) { return fun1(i); },
[](int) { return 567; } },
0);
}