Skip to content

Instantly share code, notes, and snippets.

@JPGygax68
Last active May 17, 2016 21:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JPGygax68/b96fd8a91abc24d9bc924ca8ff0888d4 to your computer and use it in GitHub Desktop.
Save JPGygax68/b96fd8a91abc24d9bc924ca8ff0888d4 to your computer and use it in GitHub Desktop.
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;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment