I would like to use polymorphism to have a vector of std::function<void(Base&)> that take in a base class as a parameter, and fill the vector with std::function with a similar signature that instead take in a derived class as a parameter.
#include <functional>
#include <vector>
#include <stdio.h>
class Base
{
public:
virtual ~Base() = default;
};
class Derived : public Base
{
public:
Derived(int x, int y) : a(x), b(y) {}
int a, b;
};
void DerivedFunction(Derived& d)
{
printf("A: %d, B: %d\n", d.a, d.b);
}
using FunctionSignature = std::function<void(Base&)>; // Changing Base& to Derived& compiles fine.
static std::vector<FunctionSignature> myVector;
int main()
{
FunctionSignature fn = [](Derived& d){ printf("A: %d, B: %d\n", d.a, d.b); };
myVector.push_back(fn); // error
myVector.push_back(std::forward<FunctionSignature>(fn)); // error
myVector.push_back(std::bind(&DerivedFunction, std::placeholders::_1)); // error
return 0;
}
What would be the correct way to push_back DerivedFunction into the vector?
Godbolt link: https://godbolt.org/z/b6Taqoqs8
A
Derived&can be implicitly converted to aBase&. Inheritance models a is-a relation: EveryDerivedinstance is-aBase. This relation is not mutual. You cannot implicitly convert aBase&to aDerived&(not everyBaseis-aDerived).You can use a
dynamic_cast. It will throw an exception when the dynamic type of the object is notDerived:Live Demo
You could catch the exception in the wrapper, or cast between pointers to get a
nullptrrather than an exception (for details see here).As mentioned in a comment, the vector is a distraction. If the first line in
mainis fixed you can use the same with the vector.