My intention in the following code is to be able to call a virtual function with a lambda as its parameter. The way I go about it is clearly not right, as virtual templates are not allowed.
Is there some way around it?
// polymorphic base class
struct B {
virtual void set_val(int) = 0;
virtual int get_val() = 0;
virtual void set_next(B*) = 0;
template<typename FCall_T> // compiler error: no virtual templates allowed
virtual void for_each_node_do(FCall_T) = 0;
};
// derived class
struct D :
public B
{
int val;
D* p_next;
void set_val(int i) override { val = i; }
int get_val() override { return val; }
void set_next(B* p_next_)override { p_next = dynamic_cast<D*>(p_next_); };
template<typename FCall_T>
void for_each_node_do(FCall_T fnc) override {
fnc(this);
D* p_cur = p_next;
while(p_cur) {
fnc(p_cur);
p_cur = p_cur->p_next;
}
}
};
int main() {
// set up linked list
int cnt = 5;
B** ppB = new B*[cnt]; // array of base class ptrs
for(int i = 0; i < cnt; ++i)
ppB[i] = new D;
for(int i = 0; i < cnt; ++i) {
ppB[i]->set_val(i);
ppB[i]->set_next( (i < cnt-1) ? ppB[i+1] : nullptr);
}
B* p_root = ppB[0]; // base class ptr
// do something thru base class ptr
p_root->for_each_node_do(
[](B* pB){
pB->set_val(pB->get_val() * 10);
}
);
// do something else thru base class ptr
p_root->for_each_node_do(
[](B* pB){
cout << pB->get_val() << endl;
}
);
return 0;
}
I considered declaring B::for_each_node_do()
as:
virtual void for_each_node_do(void(*)(B*)) = 0;
...and declaring as many free functions to use as its parameter as necessary, but as I stated above, I am wondering if there is a way to make it work with lambdas as its parameter.