I use my class as a template parameter for one of its parent class, and this parent class uses it in the template argument (although sizeof ()).
And the compiler gives me:
error: incomplete type 'Invoker :: workerClass {aka MyClass}' used in the naming specifier
However, the class is well defined in the file. I think this is due to the fact that the child class is not created at the time the base class is created, but this happens with CRTP and there are no problems.
The reason I use the child class in the template argument is to make another function call if the child class has a specific function or not.
Here is the minimum code to test
template <int X=0, class U = void> struct test { typedef U type; }; enum Commands { Swim, Fly }; template<Commands T> struct Param { }; template <class T> class Invoker { public: typedef T workerClass; workerClass *wc() { return static_cast<workerClass*>(this); } template <Commands command> void invoke() { invoke2(Param<command>()); } template<class Y=int> typename test<sizeof(Y)+sizeof(decltype(&workerClass::fly))>::type invoke2(Param<Fly>) { wc()->fly(); } template<class Y=int> typename test<sizeof(Y)+sizeof(decltype(&workerClass::swim))>::type invoke2(Param<Swim>) { wc()->shoot(); } template<Commands command> void invoke2(Param<command>) { printf("Default handler for command %d\n", command); } }; template <class T, class Inv = Invoker<T> > class BaseClass : public Inv { public: template<Commands command> void invoke() { Inv::template invoke<command>(); } }; class MyClass : public BaseClass<MyClass> { public: void swim() { printf("Swimming like a fish!\n"); } }; void testing() { MyClass foo; foo.invoke<Fly>(); foo.invoke<Swim>(); }
Error in line:
typename test<sizeof(Y)+sizeof(decltype(&workerClass::fly))>::type
So, is there any compiler that supports this, or is this explicitly specified by the standard as invalid usage of patterns? Should I change the way I do this and find a way? CRTP gives me hope that the code may be valid, but I'm not sure.
If this is really not possible, then why, and why does CRTP work?
source share