JPGygax68
5/17/2016 - 9:03 PM

Use C++11 template template parameters to add pseudo-aspects via chained inheritance

Use C++11 template template parameters to add pseudo-aspects via chained inheritance

#include <iostream>

/*=======================================================================
 * ASPECT COMPOSITION
 *======================================================================*/
 
template<class Parent>
struct Nil_aspect: public Parent
{
    void tell() {} // no-op, and ends the chain
};

template<class Parent, template<class> class ...Aspects> class Aspect_composer;

template<class Parent, template<class> class Aspect>
class Aspect_composer<Parent, Aspect>: public Aspect< Nil_aspect<Parent> > {};

template<class Parent, template<class> class FirstAspect, template<class> class ...OtherAspects>
class Aspect_composer<Parent, FirstAspect, OtherAspects...>: public FirstAspect< Aspect_composer<Parent, OtherAspects...> > {};

template<class Parent>
class Aspect1: public Parent
{
public:
    Aspect1() { std::cout << "Aspect1 here" << std::endl; }
    
    void tell() { 
        std::cout << "Hello from Aspect1" << std::endl;
        Parent::tell();
    }
};

template<class Parent>
class Aspect2: public Parent
{
public:
    Aspect2() { std::cout << "Aspect2 here" << std::endl; }
    void tell() { 
        std::cout << "Hello from Aspect2" << std::endl;
        Parent::tell();
    }
};

template<class Parent>
class Aspect3: public Parent
{
public:
    Aspect3() { std::cout << "Aspect3 here" << std::endl; }
    void tell() { 
        std::cout << "Hello from Aspect3" << std::endl;
        Parent::tell();
    }
};

class My_base {
public:
    My_base() { std::cout << "My_base here" << std::endl; }
};

class My_class: public Aspect_composer<My_base, Aspect1, Aspect2, Aspect3>
{
};

int main()
{
    My_class obj;
    
    obj.tell();
    
    std::cout << std::endl << "Press RETURN to terminate" << std::endl;
    char dummy; std::cin >> std::noskipws >> dummy;

    return 0;
}