#include <iostream>
class any {
public:
template<class T>
any(T const& i) : _erasure() {
_erasure = new derive<T>(i);
}
any() = default;
template<class T>
any& operator=(T const& i) {
if(_erasure) {
delete _erasure;
}
_erasure = new derive<T>(i);
return *this;
}
void call() const {
_erasure->call();
}
private:
struct base {
virtual ~base() {};
virtual void call() =0;
};
template<class U>
struct derive : public base{
U val;
derive(U const& i) : val(i) {};
void call() {
val.call();
}
};
base* _erasure;
};
struct hoge {
void call() const { std::cout << "hoge::call" << std::endl; }
};
struct foo {
void call() const { std::cout << "foo::call" << std::endl; }
};
int main() {
any val;
val = hoge();
val.call();
val = foo();
val.call();
}
I2luY2x1ZGUgPGlvc3RyZWFtPgoKY2xhc3MgYW55IHsKcHVibGljOgogIHRlbXBsYXRlPGNsYXNzIFQ+CiAgYW55KFQgY29uc3QmIGkpIDogX2VyYXN1cmUoKSB7CiAgICBfZXJhc3VyZSA9IG5ldyBkZXJpdmU8VD4oaSk7CiAgfQogIGFueSgpID0gZGVmYXVsdDsKCiAgdGVtcGxhdGU8Y2xhc3MgVD4KICBhbnkmIG9wZXJhdG9yPShUIGNvbnN0JiBpKSB7CiAgICBpZihfZXJhc3VyZSkgewogICAgICBkZWxldGUgX2VyYXN1cmU7CiAgICB9CiAgICBfZXJhc3VyZSA9IG5ldyBkZXJpdmU8VD4oaSk7CiAgICByZXR1cm4gKnRoaXM7CiAgfQoKICB2b2lkIGNhbGwoKSBjb25zdCB7IAogICAgX2VyYXN1cmUtPmNhbGwoKTsKICB9Cgpwcml2YXRlOgogIHN0cnVjdCBiYXNlIHsKICAgIHZpcnR1YWwgfmJhc2UoKSB7fTsKICAgIHZpcnR1YWwgdm9pZCBjYWxsKCkgPTA7CiAgfTsKCiAgdGVtcGxhdGU8Y2xhc3MgVT4KICBzdHJ1Y3QgZGVyaXZlIDogcHVibGljIGJhc2V7CiAgICBVIHZhbDsKICAgIGRlcml2ZShVIGNvbnN0JiBpKSA6IHZhbChpKSB7fTsKICAgIHZvaWQgY2FsbCgpIHsKICAgICAgdmFsLmNhbGwoKTsKICAgIH0KICB9OwoKICBiYXNlKiBfZXJhc3VyZTsKfTsKCnN0cnVjdCBob2dlIHsKICB2b2lkIGNhbGwoKSBjb25zdCB7IHN0ZDo6Y291dCA8PCAiaG9nZTo6Y2FsbCIgPDwgc3RkOjplbmRsOyB9Cn07CgpzdHJ1Y3QgZm9vIHsKICB2b2lkIGNhbGwoKSBjb25zdCB7IHN0ZDo6Y291dCA8PCAiZm9vOjpjYWxsIiA8PCBzdGQ6OmVuZGw7IH0KfTsKCmludCBtYWluKCkgewogIGFueSB2YWw7CgogIHZhbCA9IGhvZ2UoKTsKICB2YWwuY2FsbCgpOwoKICB2YWwgPSBmb28oKTsKICB2YWwuY2FsbCgpOwp9