#include <iostream>
#include <string>
using namespace std;
template <typename T>
class Base {
public:
Base(const T& t) : _t(t) {}
virtual ~Base() { }
void doSomething() { cout << "Hello world\n"; }
virtual T getVal() const { return _t; }
private:
T _t;
};
class DerivedA : public virtual Base<string>
{
public:
DerivedA(const string& path) : Base<string>(path) {}
virtual ~DerivedA() {}
};
namespace details {
template<typename T>
Base<T>* make_base(Base<T>* param) { return param; }
}
template<typename T>
auto make_base(T& param) -> decltype(details::make_base(¶m)) { return details::make_base(¶m); }
int main() {
DerivedA foo("foo"s);
auto bar = make_base(foo);
bar->doSomething();
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8c3RyaW5nPgoKdXNpbmcgbmFtZXNwYWNlIHN0ZDsKCnRlbXBsYXRlIDx0eXBlbmFtZSBUPgpjbGFzcyBCYXNlIHsKcHVibGljOgogICAgQmFzZShjb25zdCBUJiB0KSA6IF90KHQpIHt9CiAgICB2aXJ0dWFsIH5CYXNlKCkgeyB9CgogICAgdm9pZCBkb1NvbWV0aGluZygpIHsgY291dCA8PCAiSGVsbG8gd29ybGRcbiI7IH0KCiAgICB2aXJ0dWFsIFQgZ2V0VmFsKCkgY29uc3QgeyByZXR1cm4gX3Q7IH0KCnByaXZhdGU6CiAgICBUIF90Owp9OwoKY2xhc3MgRGVyaXZlZEEgOiBwdWJsaWMgdmlydHVhbCBCYXNlPHN0cmluZz4KewpwdWJsaWM6CiAgICBEZXJpdmVkQShjb25zdCBzdHJpbmcmIHBhdGgpIDogQmFzZTxzdHJpbmc+KHBhdGgpIHt9CiAgICB2aXJ0dWFsIH5EZXJpdmVkQSgpIHt9Cn07CgpuYW1lc3BhY2UgZGV0YWlscyB7CiAgICB0ZW1wbGF0ZTx0eXBlbmFtZSBUPgogICAgQmFzZTxUPiogbWFrZV9iYXNlKEJhc2U8VD4qIHBhcmFtKSB7IHJldHVybiBwYXJhbTsgfQp9Cgp0ZW1wbGF0ZTx0eXBlbmFtZSBUPgphdXRvIG1ha2VfYmFzZShUJiBwYXJhbSkgLT4gZGVjbHR5cGUoZGV0YWlsczo6bWFrZV9iYXNlKCZwYXJhbSkpIHsgcmV0dXJuIGRldGFpbHM6Om1ha2VfYmFzZSgmcGFyYW0pOyB9CgppbnQgbWFpbigpIHsKICBEZXJpdmVkQSBmb28oImZvbyJzKTsKICBhdXRvIGJhciA9IG1ha2VfYmFzZShmb28pOwogIAogIGJhci0+ZG9Tb21ldGhpbmcoKTsKfQ==