Not that there's anything necessarily wrong with it, per se, but I honestly don't see why you would want to do things like that. It just seems overly complicated and the amount of work required doesn't justify (in my mind, at least) whatever benefits it may have.
That aside, for the constructor base-class initializer you have:
Code:
: callback_base(sc)
Some compilers will accept that, but the correct way to do it is to explicitly provide the template parameter, eg:
Code:
: callback_base<SomeClass>(sc)
And the code formatting is pretty terrible - it's very difficult to follow the way it's structured. I'd recommend something along the lines of:
Code:
#include <iostream>
template<typename SELF_TYPE>
class callback_base
{
public: typedef SELF_TYPE self_type;
public: callback_base(SELF_TYPE& self_) : self(self_) { }
//public: SELF_TYPE& GetSelf() { return self; }
protected: SELF_TYPE& self;
};
class SomeClass
{
public: void Start()
{
std::cout << "SomeClass::Start" << std::endl;
struct Callback1 : callback_base<SomeClass>
{
Callback1(SomeClass& sc)
:callback_base<SomeClass>(sc)
{ }
void Invoke(unsigned int a1, unsigned int a2)
{
std::cout << "Callback1::Invoke" << std::endl;
struct Callback2 : callback_base<SomeClass>
{
Callback2(SomeClass& sc)
: callback_base<SomeClass>(sc)
{ }
void Invoke(const char* a1)
{
std::cout << "Callback2::Invoke" << std::endl;
struct Callback3 : callback_base<SomeClass>
{
Callback3(SomeClass& sc)
: callback_base<SomeClass>(sc)
{ }
void Invoke(bool a1)
{
std::cout << "Callback3::Invoke" << std::endl;
}
};
Callback3 cb3(self);
cb3.Invoke(true); //temp
}
};
Callback2 cb2(self);
cb2.Invoke("some argument"); //temp
struct Callback4 : callback_base<SomeClass>
{
Callback4(SomeClass& sc)
: callback_base<SomeClass>(sc)
{ }
void Invoke(int a1)
{
std::cout << "Callback4::Invoke" << std::endl;
self.End();
}
};
Callback4 cb4(self);
cb4.Invoke(1); //temp
}
};
Callback1 cb1(*this);
cb1.Invoke(2, 2); //temp
}
public: void End()
{
std::cout << "SomeClass::End" << std::endl;
}
};
int main()
{
SomeClass someClass;
someClass.Start();
std::cin.get();
}