#include <memory>
class generic {
class underlying_base {
public:
virtual ~underlying_base(){}
virtual void SomeGenericMethod()=0;
};
template <class T>
class underlying_impl : public underlying_base {
T data;
public:
underlying_impl(const T& d) :data(d) {}
virtual void SomeGenericMethod()
{return data.SomeGenericMethod();}
};
public:
std::unique_ptr<underlying_base> data;
template < class T > void setOther(const T& other) {
data.reset(new underlying_impl<T>(other));
}
void doSomethingWithOther() {
data->SomeGenericMethod();
}
};
#include <iostream>
struct Bar {
void SomeGenericMethod() {std::cout << "BAR\n";}
};
int main(int argc, char **argv) {
generic fObj;
Bar bObj;
fObj.setOther(bObj);
fObj.doSomethingWithOther();
return 0;
}
I2luY2x1ZGUgPG1lbW9yeT4KCmNsYXNzIGdlbmVyaWMgewogICAgY2xhc3MgdW5kZXJseWluZ19iYXNlIHsKICAgIHB1YmxpYzoKICAgICAgICB2aXJ0dWFsIH51bmRlcmx5aW5nX2Jhc2UoKXt9CiAgICAgICAgdmlydHVhbCB2b2lkIFNvbWVHZW5lcmljTWV0aG9kKCk9MDsKICAgIH07CiAgICB0ZW1wbGF0ZSA8Y2xhc3MgVD4KICAgIGNsYXNzIHVuZGVybHlpbmdfaW1wbCA6IHB1YmxpYyB1bmRlcmx5aW5nX2Jhc2UgewogICAgICAgIFQgZGF0YTsKICAgIHB1YmxpYzoKICAgICAgICB1bmRlcmx5aW5nX2ltcGwoY29uc3QgVCYgZCkgOmRhdGEoZCkge30KICAgICAgICB2aXJ0dWFsIHZvaWQgU29tZUdlbmVyaWNNZXRob2QoKSAKICAgICAgICB7cmV0dXJuIGRhdGEuU29tZUdlbmVyaWNNZXRob2QoKTt9CiAgICB9OwogICAgcHVibGljOgogICAgICAgIHN0ZDo6dW5pcXVlX3B0cjx1bmRlcmx5aW5nX2Jhc2U+IGRhdGE7CgogICAgICAgIHRlbXBsYXRlIDwgY2xhc3MgVCA+IHZvaWQgc2V0T3RoZXIoY29uc3QgVCYgb3RoZXIpIHsKICAgICAgICAgICAgZGF0YS5yZXNldChuZXcgdW5kZXJseWluZ19pbXBsPFQ+KG90aGVyKSk7CiAgICAgICAgfQoKICAgICAgICB2b2lkIGRvU29tZXRoaW5nV2l0aE90aGVyKCkgewogICAgICAgICAgICBkYXRhLT5Tb21lR2VuZXJpY01ldGhvZCgpOwogICAgICAgIH0KfTsKCiNpbmNsdWRlIDxpb3N0cmVhbT4Kc3RydWN0IEJhciB7CiAgICB2b2lkIFNvbWVHZW5lcmljTWV0aG9kKCkge3N0ZDo6Y291dCA8PCAiQkFSXG4iO30KfTsKCmludCBtYWluKGludCBhcmdjLCBjaGFyICoqYXJndikgewogICAgZ2VuZXJpYyBmT2JqOwogICAgQmFyIGJPYmo7CiAgICBmT2JqLnNldE90aGVyKGJPYmopOwogICAgZk9iai5kb1NvbWV0aGluZ1dpdGhPdGhlcigpOwogICAgcmV0dXJuIDA7Cn0=