#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;
}