Skip to content

Instantly share code, notes, and snippets.

@odeblic
Last active July 27, 2017 11:23
Show Gist options
  • Save odeblic/575cf21e4a00b66c65b2b38e395f9643 to your computer and use it in GitHub Desktop.
Save odeblic/575cf21e4a00b66c65b2b38e395f9643 to your computer and use it in GitHub Desktop.
Inherit several bases by using variadic templates
#include <iostream>
#include <type_traits>
#include <typeinfo>
template <typename BASE, typename ... BASES>
struct MultiDerived : BASE, MultiDerived<BASES> ...
{
void EveryAction()
{
BASE::Action();
int dummy[sizeof...(BASES)] = {(BASES::Action(), 0)...};
}
};
template <typename CLASS, typename BASE>
struct Derived : virtual CLASS, BASE
{
};
template <typename CLASS, typename BASE, typename ... BASES>
struct UniquelyDerived : UniquelyDerived<UniquelyDerived<CLASS, BASE>, UniquelyDerived<CLASS, BASES ...>>
{
};
template <typename CLASS, typename BASE>
struct UniquelyDerived<CLASS, BASE> : /* virtual */ std::conditional<std::is_base_of<BASE, CLASS>::value, CLASS, Derived<CLASS, BASE>>::type
{
void EveryAction()
{
}
};
struct Base1
{
Base1() { std::cout << "Base1::Base1()" << std::endl; }
void Action() { std::cout << "Base1::Action()" << std::endl; }
};
struct Base2
{
Base2() { std::cout << "Base2::Base2()" << std::endl; }
void Action() { std::cout << "Base2::Action()" << std::endl; }
};
struct Base3
{
Base3() { std::cout << "Base3::Base3()" << std::endl; }
void Action() { std::cout << "Base3::Action()" << std::endl; }
};
struct Base4
{
Base4() { std::cout << "Base4::Base4()" << std::endl; }
void Action() { std::cout << "Base4::Action()" << std::endl; }
};
struct Base5
{
Base5() { std::cout << "Base5::Base5()" << std::endl; }
void Action() { std::cout << "Base5::Action()" << std::endl; }
};
template <typename T>
void print_info()
{
std::cout << "------------------------------" << std::endl;
std::cout << "Construction of the object:" << std::endl;
T object{};
std::cout << "Use of the object:" << std::endl;
object.EveryAction();
std::cout << "Info about the object:" << std::endl;
std::cout << "- type is " << typeid(T).name() << std::endl;
std::cout << "- size is " << sizeof(T) << std::endl;
std::cout << "------------------------------" << std::endl;
}
int main()
{
print_info<MultiDerived<Base1>>();
print_info<MultiDerived<Base2, Base4>>();
print_info<MultiDerived<Base3, Base4, Base5>>();
//print_info<MultiDerived<Base5, Base5>>();
std::cout << "------------------------------" << std::endl;
//print_info<UniquelyDerived<Base1>>();
print_info<UniquelyDerived<Base1, Base2>>();
print_info<UniquelyDerived<Base1, Base2, Base2>>();
print_info<UniquelyDerived<Base1, Base2, Base2, Base2>>();
print_info<UniquelyDerived<Base1, Base2, Base3, Base4, Base5>>();
print_info<UniquelyDerived<Base1, Base2, Base3, Base4, Base4, Base4>>();
print_info<UniquelyDerived<Base1, Base2, Base3, Base4, Base5, Base1>>();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment