#define OPTION 1 // OPTION 2 : broken, OPTION 1 : works

#include <iostream>
#include <type_traits>
using namespace std;


template <typename T,typename Enable=void>
struct child;

template <typename T>
struct base
{
	typedef T type;	
	
	#if OPTION ==1
	struct base_tag{};
	
	#endif

};


#if OPTION ==2
template <typename T>
struct child < T, typename std::enable_if < std::is_base_of< base<typename T::type>, T>::value>::type>
{

	 const char* value = "specialization";
};
#else

template <typename T>
struct child < T, std::void_t<typename T::base_tag> >
{

	 const char* value = "specialization";
};

#endif



template <typename T>
struct dervived : base<T>
{
		child<dervived> child_;
		typedef T type;	
};



int main() {
	
	
	std::cout << dervived<int>().child_.value << std::endl;
	return 0;
}