#include <type_traits>
#include <iostream>
//classes
struct A { virtual ~A(){} virtual void print(){std::cout << "A\n";}};
struct B : A { virtual void print(){std::cout << "B\n";}};
struct C : A { virtual void print(){std::cout << "C\n";}};
struct D : A { virtual void print(){std::cout << "D\n";}};
//polymorphic local forwarder
template<class Type, class FuncType>
auto poly_local(FuncType func) -> decltype(func(std::declval<Type&>()))
{
Type local;
return func(local);
}
//test function
char dowork(A& a) {
a.print();
return '8';
}
//test functionoid with parameters
struct dowork2 {
int parameter;
explicit dowork2(int p) :parameter(p) {}
int operator()(A& a) const{
a.print();
std::cout << parameter << '\n';
return parameter;
}
};
//demo
int main() {
int some_var = 2;
switch (some_var) {
case 1: poly_local<A>(dowork); break;
case 2: poly_local<B>(dowork); break;
default: poly_local<C>(dowork); break;
}
switch (some_var) {
case 1: poly_local<B>(dowork2(3)); break;
case 2: poly_local<C>(dowork2(2)); break;
default: poly_local<A>(dowork2(1)); break;
}
return 0;
}
I2luY2x1ZGUgPHR5cGVfdHJhaXRzPiAKI2luY2x1ZGUgPGlvc3RyZWFtPgoKLy9jbGFzc2VzCnN0cnVjdCBBIHsgdmlydHVhbCB+QSgpe30gdmlydHVhbCB2b2lkIHByaW50KCl7c3RkOjpjb3V0IDw8ICJBXG4iO319OwpzdHJ1Y3QgQiA6IEEgeyB2aXJ0dWFsIHZvaWQgcHJpbnQoKXtzdGQ6OmNvdXQgPDwgIkJcbiI7fX07CnN0cnVjdCBDIDogQSB7IHZpcnR1YWwgdm9pZCBwcmludCgpe3N0ZDo6Y291dCA8PCAiQ1xuIjt9fTsKc3RydWN0IEQgOiBBIHsgdmlydHVhbCB2b2lkIHByaW50KCl7c3RkOjpjb3V0IDw8ICJEXG4iO319OwoKLy9wb2x5bW9ycGhpYyBsb2NhbCBmb3J3YXJkZXIKdGVtcGxhdGU8Y2xhc3MgVHlwZSwgY2xhc3MgRnVuY1R5cGU+CmF1dG8gcG9seV9sb2NhbChGdW5jVHlwZSBmdW5jKSAtPiBkZWNsdHlwZShmdW5jKHN0ZDo6ZGVjbHZhbDxUeXBlJj4oKSkpCnsKICAgIFR5cGUgbG9jYWw7CiAgICByZXR1cm4gZnVuYyhsb2NhbCk7Cn0KCi8vdGVzdCBmdW5jdGlvbgpjaGFyIGRvd29yayhBJiBhKSB7CiAgICBhLnByaW50KCk7CiAgICByZXR1cm4gJzgnOwp9Ci8vdGVzdCBmdW5jdGlvbm9pZCB3aXRoIHBhcmFtZXRlcnMKc3RydWN0IGRvd29yazIgewogICAgaW50IHBhcmFtZXRlcjsKICAgIGV4cGxpY2l0IGRvd29yazIoaW50IHApIDpwYXJhbWV0ZXIocCkge30KICAgIGludCBvcGVyYXRvcigpKEEmIGEpIGNvbnN0ewogICAgICAgIGEucHJpbnQoKTsKICAgICAgICBzdGQ6OmNvdXQgPDwgcGFyYW1ldGVyIDw8ICdcbic7CiAgICAgICAgcmV0dXJuIHBhcmFtZXRlcjsKICAgIH0KfTsKCi8vZGVtbwppbnQgbWFpbigpIHsKICAgIGludCBzb21lX3ZhciA9IDI7CgkKICAgIHN3aXRjaCAoc29tZV92YXIpIHsKICAgIGNhc2UgMTogcG9seV9sb2NhbDxBPihkb3dvcmspOyBicmVhazsKICAgIGNhc2UgMjogcG9seV9sb2NhbDxCPihkb3dvcmspOyBicmVhazsKICAgIGRlZmF1bHQ6IHBvbHlfbG9jYWw8Qz4oZG93b3JrKTsgYnJlYWs7CiAgICB9CgogICAgc3dpdGNoIChzb21lX3ZhcikgewogICAgY2FzZSAxOiBwb2x5X2xvY2FsPEI+KGRvd29yazIoMykpOyBicmVhazsKICAgIGNhc2UgMjogcG9seV9sb2NhbDxDPihkb3dvcmsyKDIpKTsgYnJlYWs7CiAgICBkZWZhdWx0OiBwb2x5X2xvY2FsPEE+KGRvd29yazIoMSkpOyBicmVhazsKICAgIH0KICAgIHJldHVybiAwOwp9