#include <iostream>
#include <string>
using namespace std;
class Thing {
public:
virtual const char * type_name()=0;
};
class OtherThing : public Thing {
public:
OtherThing() {}
const char * type_name() { return "test"; }
};
class ParameterThing : public Thing {
std::string var;
public:
ParameterThing(const std::string var_) { var = var_; }
const char * type_name() { return var.c_str(); }
};
class NotAThing {
public:
};
template <typename TO_T, class ...Args>
inline TO_T* turn_thing_to(Thing* p, Args&&... args)
{
static_assert(std::is_base_of<Thing, TO_T>::value, "TO_T is not derived from Thing");
TO_T * newtype = new TO_T(args...);
p = newtype;
return newtype;
}
int main() {
Thing * thing = 0;
thing = turn_thing_to<OtherThing>(thing);
//compiler can't assign it to the pointer directory from the function argument, so
//I returned it.
std::cout << thing->type_name() << "\n";
thing = turn_thing_to<ParameterThing>(thing, "test2");
std::cout << thing->type_name();
/*
thing = turn_thing_to<NotAThing>(thing); //gives compile error
*/
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8c3RyaW5nPgoKdXNpbmcgbmFtZXNwYWNlIHN0ZDsKCmNsYXNzIFRoaW5nIHsKcHVibGljOgoJdmlydHVhbCBjb25zdCBjaGFyICogdHlwZV9uYW1lKCk9MDsKfTsKCmNsYXNzIE90aGVyVGhpbmcgOiBwdWJsaWMgVGhpbmcgewpwdWJsaWM6CglPdGhlclRoaW5nKCkge30KCWNvbnN0IGNoYXIgKiB0eXBlX25hbWUoKSB7IHJldHVybiAidGVzdCI7IH0KfTsKCmNsYXNzIFBhcmFtZXRlclRoaW5nIDogcHVibGljIFRoaW5nIHsKCXN0ZDo6c3RyaW5nIHZhcjsKcHVibGljOgoJUGFyYW1ldGVyVGhpbmcoY29uc3Qgc3RkOjpzdHJpbmcgdmFyXykgeyB2YXIgPSB2YXJfOyB9Cgljb25zdCBjaGFyICogdHlwZV9uYW1lKCkgeyByZXR1cm4gdmFyLmNfc3RyKCk7IH0KfTsKCmNsYXNzIE5vdEFUaGluZyB7CnB1YmxpYzoKfTsKCnRlbXBsYXRlIDx0eXBlbmFtZSBUT19ULCBjbGFzcyAuLi5BcmdzPgppbmxpbmUgVE9fVCogdHVybl90aGluZ190byhUaGluZyogcCwgQXJncyYmLi4uIGFyZ3MpIAp7CiAgc3RhdGljX2Fzc2VydChzdGQ6OmlzX2Jhc2Vfb2Y8VGhpbmcsIFRPX1Q+Ojp2YWx1ZSwgIlRPX1QgaXMgbm90IGRlcml2ZWQgZnJvbSBUaGluZyIpOwogIFRPX1QgKiBuZXd0eXBlID0gbmV3IFRPX1QoYXJncy4uLik7IAogIHAgPSBuZXd0eXBlOwogIHJldHVybiBuZXd0eXBlOwp9CgppbnQgbWFpbigpIHsKCVRoaW5nICogdGhpbmcgPSAwOwoJdGhpbmcgPSB0dXJuX3RoaW5nX3RvPE90aGVyVGhpbmc+KHRoaW5nKTsKCS8vY29tcGlsZXIgY2FuJ3QgYXNzaWduIGl0IHRvIHRoZSBwb2ludGVyIGRpcmVjdG9yeSBmcm9tIHRoZSBmdW5jdGlvbiBhcmd1bWVudCwgc28KCS8vSSByZXR1cm5lZCBpdC4KCXN0ZDo6Y291dCA8PCB0aGluZy0+dHlwZV9uYW1lKCkgPDwgIlxuIjsKCXRoaW5nICA9IHR1cm5fdGhpbmdfdG88UGFyYW1ldGVyVGhpbmc+KHRoaW5nLCAidGVzdDIiKTsKCXN0ZDo6Y291dCA8PCB0aGluZy0+dHlwZV9uYW1lKCk7CgkKCS8qCgl0aGluZyA9IHR1cm5fdGhpbmdfdG88Tm90QVRoaW5nPih0aGluZyk7IC8vZ2l2ZXMgY29tcGlsZSBlcnJvcgoJKi8KCXJldHVybiAwOwp9