Here’s an option:
#include <iostream>
#include <type_traits>
#include <string>
template <class, template <class> class>
struct is_instance : public std::false_type {};
template <class T, template <class> class U>
struct is_instance<U<T>, U> : public std::true_type {};
template <class>
class Second
{};
int main()
{
using A = Second<int>;
using B = Second<std::string>;
using C = float;
std::cout << is_instance<A, Second>{} << '\n'; // prints 1
std::cout << is_instance<B, Second>{} << '\n'; // prints 1
std::cout << is_instance<C, Second>{} << '\n'; // prints 0
}
It’s basically specializing the is_instance
struct for types that are instantiations of a template.