#include <iostream>
#include <typeinfo>
#include <type_traits>

using namespace std;

struct Grandma          {};
struct Mom : Grandma    {};
struct Son : Mom        {};
struct Grandchild : Son {};


template<typename...Ts>
struct LCA;

template<typename T1, typename T2, typename...Ts>
struct LCA<T1, T2, Ts...>
{
	using base = typename std::conditional
	<
		std::is_base_of<T1, T2>::value, T1,
		typename std::conditional <
			std::is_base_of<T2, T1>::value, T2, void
		>::type
	>::type;

	using type = typename LCA<base, Ts...>::type;
};

template<typename T>
struct LCA<T>
{
	using type = T;
};


int main() 
{
	LCA<Son, Grandchild, Son>::type      obj1;
	LCA<Son, Grandchild, Mom, Son>::type obj2;
	LCA<Mom, Mom, Mom>::type             obj3;

	cout << "obj1 type = " << typeid(obj1).name() << endl;
	cout << "obj2 type = " << typeid(obj2).name() << endl;
	cout << "obj3 type = " << typeid(obj3).name() << endl;

	return 0;
}