#include <iostream>
#include <type_traits>
template<typename Derived>
class MyObject {
public:
MyObject() : theRealInstance(static_cast<Derived*>(this)) {
// Check the available interface as soon an instance is created
void (Derived::*op1)(void) = &Derived::methodImpl;
(void)op1;
}
void method() {
theRealInstance->methodImpl();
}
private:
Derived* theRealInstance;
};
struct MyImpl : public MyObject<MyImpl> {
void methodImpl() { std::cout << "method implementation" << std::endl; }
};
struct MyWrongImpl : public MyObject<MyWrongImpl> {
};
void test_alias(){
MyImpl m;
m.method();
// Uncomment to see the compile time error
// MyWrongImpl w;
}
int main() {
test_alias();
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dHlwZV90cmFpdHM+Cgp0ZW1wbGF0ZTx0eXBlbmFtZSBEZXJpdmVkPgpjbGFzcyBNeU9iamVjdCB7CnB1YmxpYzoKICAgIE15T2JqZWN0KCkgOiB0aGVSZWFsSW5zdGFuY2Uoc3RhdGljX2Nhc3Q8RGVyaXZlZCo+KHRoaXMpKSB7CiAgICAgICAgLy8gQ2hlY2sgdGhlIGF2YWlsYWJsZSBpbnRlcmZhY2UgYXMgc29vbiBhbiBpbnN0YW5jZSBpcyBjcmVhdGVkCiAgICAgICAgdm9pZCAoRGVyaXZlZDo6Km9wMSkodm9pZCkgPSAmRGVyaXZlZDo6bWV0aG9kSW1wbDsKICAgICAgICAodm9pZClvcDE7CiAgICB9CiAgICAKICAgIHZvaWQgbWV0aG9kKCkgeyAKICAgICAgICB0aGVSZWFsSW5zdGFuY2UtPm1ldGhvZEltcGwoKTsgCiAgICB9Cgpwcml2YXRlOgogICAgRGVyaXZlZCogdGhlUmVhbEluc3RhbmNlOwp9OwoKc3RydWN0IE15SW1wbCA6IHB1YmxpYyBNeU9iamVjdDxNeUltcGw+IHsKICAgIHZvaWQgbWV0aG9kSW1wbCgpIHsgc3RkOjpjb3V0IDw8ICJtZXRob2QgaW1wbGVtZW50YXRpb24iIDw8IHN0ZDo6ZW5kbDsgfQp9OwoKc3RydWN0IE15V3JvbmdJbXBsIDogcHVibGljIE15T2JqZWN0PE15V3JvbmdJbXBsPiB7Cn07Cgp2b2lkIHRlc3RfYWxpYXMoKXsKICAgIE15SW1wbCBtOwogICAgbS5tZXRob2QoKTsKCiAgICAvLyBVbmNvbW1lbnQgdG8gc2VlIHRoZSBjb21waWxlIHRpbWUgZXJyb3IKICAgIC8vIE15V3JvbmdJbXBsIHc7Cn0KCmludCBtYWluKCkgewoJdGVzdF9hbGlhcygpOwoJcmV0dXJuIDA7Cn0=