The following solution works with protected inheritance.
template class BaseTemplate, typename Derived, typename TCheck = void>
struct test_base_template;
template class BaseTemplate, typename Derived>
using is_base_template_of = typename test_base_template::is_base;
//Derive - is a class. Let inherit from Derive, so it can cast to its protected parents
template class BaseTemplate, typename Derived>
struct test_base_template>> : Derived
{
template
static constexpr std::true_type test(BaseTemplate *);
static constexpr std::false_type test(...);
using is_base = decltype(test((test_base_template *) nullptr));
};
//Derive - is not a class, so it is always false_type
template class BaseTemplate, typename Derived>
struct test_base_template>>
{
using is_base = std::false_type;
};
Surprisingly, on VS2017, it works with multiple inheritance from the same template, like C< int > and C< float > both. (have no idea how!)
Check the Link to test code