我假设第一个需求是可行的,方法基于
detection idiom
:
namespace detail
{
template<template<typename...> typename T, typename AlwaysVoid, typename... Ts>
struct is_template_instantiable :
std::false_type {};
template<template<typename...> typename T, typename... Ts>
struct is_template_instantiable<T, std::void_t<T<Ts...>>, Ts...> :
std::true_type {};
template<template<typename...> typename T, typename... Ts>
inline constexpr auto is_template_instantiable_v =
is_template_instantiable<T, void, Ts...>::value;
}
然后,使用:
template<typename T = void>
struct X{};
它产生:
static_assert(detail::is_template_instantiable_v<X>);
static_assert(detail::is_template_instantiable_v<X, void>);
static_assert(!detail::is_template_instantiable_v<X, void, int>);
EXAMPLE
然而,有了这种特质,我无法解决第二个挑战…