1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
|
#include <iostream>
template <int> struct AComponent; template <int> struct BComponent;
struct A {
template <int N> using component_type = AComponent<N>; // *** Added
};
struct B {
template <int N> using component_type = BComponent<N>; // *** Added
};
struct Visitor {
private:
template<int, typename> class CreateComponents; // *** Added
public:
template <int N> void visit (struct AComponent<N>*) const {std::cout << "AComponent<" << N << "> visited.\n";}
template <int N> void visit (struct BComponent<N>*) const {std::cout << "BComponent<" << N << "> visited.\n";}
template <int N, typename T> void createComponents (int n, const T* t) const { // *** Modified. All overloads expressed as a single template function with T now.
CreateComponents<N,T>(*this)(n, t); // Must pass *this into the CreateComponents<N,T> constructor.
}
};
template <int N>
struct AComponent {
AComponent(const A*) {}
void accept (const Visitor& visitor) {visitor.visit(this);}
};
template <int N>
struct BComponent {
BComponent(const B*) {}
void accept (const Visitor& visitor) {visitor.visit(this);}
};
template<int N, typename T>
class Visitor::CreateComponents : public CreateComponents<N + 1, T> {
private:
const Visitor& visitor;
public:
CreateComponents (const Visitor& v) : CreateComponents<N + 1, T>(v), visitor(v) {}
void operator()(int n, const T* t) const {
if (n == N) {
typename T::template component_type<N>* component = new typename T::template component_type<N>(t); // Template disambiguator needed with GCC 4.8.1.
// Code X
component->accept(visitor); // accept visitor instead of *this now.
// Code Y
return;
}
CreateComponents<N + 1, T>::operator()(n, t);
}
};
template<typename T>
class Visitor::CreateComponents<20, T> { // Because partial specialization of a member function is not allowed, the function object Visitor::CreateComponents is needed.
private:
const Visitor& visitor;
public:
CreateComponents (const Visitor& v) : visitor(v) {}
void operator()(int, const T*) const {} // End of recursion
};
int main() {
A* a = new A;
B* b = new B;
Visitor visitor;
const int num = 5; // some random number
visitor.createComponents<0>(num, a); // AComponent<5> visited.
visitor.createComponents<0>(num, b); // BComponent<5> visited.
}
|