#include <iostream>
using namespace std;
// -------------------------------------
// Executer
template <class T, class M0, class M1> class Executer {
public:
void operator()(T &klass) {
cout << "execute: " << klass.i << endl;
M0()(klass);
M1()(klass);
}
};
// -------------------------------------
// Method0
template <class T> class Method0 {
public:
void operator()(T &klass);
};
// -------------------------------------
// CommonMethod1
template <class T> class CommonMethod1 {
public:
void operator()(T &klass) {
cout << "\tMethod1 for Klass0 and Klass1: " << klass.i << endl;
}
};
// -------------------------------------
// Klass0
class Klass0 {
using this_t = Klass0;
using executer_t = Executer<this_t, Method0<this_t>, CommonMethod1<this_t>>;
friend executer_t;
friend class Method0<this_t>;
friend class CommonMethod1<this_t>;
public:
Klass0(int j) : i(j) {}
void execute() { executer_t()(*this); }
private:
int i;
};
// -------------------------------------
// Method0<Klass0>
template <> void Method0<Klass0>::operator()(Klass0 &klass) {
cout << "\tMethod0 for Klass0: " << klass.i << endl;
}
// -------------------------------------
// Klass1
class Klass1 {
using this_t = Klass1;
using executer_t = Executer<this_t, Method0<this_t>, CommonMethod1<this_t>>;
friend executer_t;
friend class Method0<this_t>;
friend class CommonMethod1<this_t>;
public:
Klass1(int j) : i(j) {}
void execute() { executer_t()(*this); }
private:
int i;
};
// -------------------------------------
// Method0<Klass1>
template <> void Method0<Klass1>::operator()(Klass1 &klass) {
cout << "\tMethod0 for Klass1: " << klass.i << endl;
}
// -------------------------------------
int main() {
Klass0(0).execute();
Klass1(1).execute();
}