For many years, I always used the following piece of code to detect if an arbitrary type is a template instantiation:
namespace priv {
template <typename, template <typename...> typename>
struct _is_instance_impl : public std::false_type {};
template <template <typename...> typename U, typename...Ts>
struct _is_instance_impl<U<Ts...>, U> : public std::true_type {};
}
template <typename T, template <typename ...> typename U>
using is_instance = priv::_is_instance_impl<std::decay_t<T>, U>;
This also works fine with C++20 concepts:
template <typename T, template <typename ...> typename U>
concept instance_of = priv::_is_instance_impl<std::decay_t<T>, U>::value;
template <typename T>
std::size_t len_of(T &&s) requires instance_of<T, std::basic_string> {
return s.length();
}
I have attempted to replace this SFINAE-based code with a C++20 requires() expression, without luck.
Has anyone any idea on how this could be accomplished, if it is actually possible at all?