In C++: CRTP to avoid dynamic polymorphism, the next option would be suggested to prevent the overhead of virtual member functions and impose a particular interface:

template <class Derived>
struct base {
  void foo() {
    static_cast<Derived *>(this)->foo();
  };
};

struct my_type : base<my_type> {
  void foo() {}; // required to compile. < Don't see why
};

struct your_type : base<your_type> {
  void foo() {}; // required to compile. < Don't see why
};

Nevertheless it appears the derived class doesn't need a definition to compile because it gets one (the code compiles fine without determining a my_type::foo). Actually if your function is supplied, the bottom function won't be known as while using the derived class.

So now you ask ,, may be the following code alternative acceptable (and standard?):

template <class Derived>
struct base {
  void foo() {
    // Generate a meaningful error if called
    (void)sizeof( Derived::foo_IS_MISSING );
  };
};

struct my_type : base<my_type> {
  void foo() {}; // required to compile.
};

struct your_type : base<your_type> {
  void foo() {}; // required to compile.
};

int main() {
  my_type my_obj;
  my_obj.foo(); // will fail if foo missing in derived class
}

The entire reason for this pattern is, so far as I realize, that you could pass arguments simply as template <typename T> base<T> & as well as your interface is determined by (non-virtual) functions in base<T>. Without having an interface that you would like to define (when you are recommending within the second a part of your question), then you shouldn't have for just about any of the to begin with.

Note that you're not "imposing" an interface as with pure virtual functions, but instead you're supplying an interface. Since things are resolved at compile time, "imposing" is not this type of strong requirement.

Nevertheless it appears the derived class doesn't need a definition to compile because it gets one (the code compiles fine without determining a my_type::foo).

C++ is lazy : it won't attempt to make base<my_type>::foo() if you don't really utilize it. But when you use it, then it will likely be produced and when that fails, compilation errors will flow. However in your situation, base<my_type>::foo() could be instanciated all right :

template <class Derived>
struct base {
  void foo() {
    static_cast<Derived *>(this)->foo();
  };
};

struct my_type : base<my_type> {};

void func() {
    my_type m;
    static_cast<base<my_type>& >(m).foo();
}

will compile all right. Once the compiler is given static_cast(this)->foo(), it'll try to look for a foo() that's available in my_type. And there's one: it's known as base<my_type>::foo(), that is public from the openly inherited class. so base<my_type>::foo() calls base<my_type>::foo(), and also you have an infinite recursion.

No, think of the following situation:

template <typename T>
void bar(base<T> obj) {
   obj.foo();
}

base<my_type> my_obj;
bar(my_obj);

Base's foo is going to be known as rather than my_type's...

Do that, and you'll get the erro message:

template <class Derived>
struct base {
  void foo() {
    sizeof(Derived::foo);
    static_cast<Derived *>(this)->foo();
  };
};

However I must confess I don't know how this works in compilers apart from GCC, examined just with GCC.

Inside your alternative code you cannot "polymorphically" call foo on the base<T>.