diff options
Diffstat (limited to 'development/c++/tmpl-void_t.cc')
-rw-r--r-- | development/c++/tmpl-void_t.cc | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/development/c++/tmpl-void_t.cc b/development/c++/tmpl-void_t.cc new file mode 100644 index 0000000..fd95315 --- /dev/null +++ b/development/c++/tmpl-void_t.cc @@ -0,0 +1,47 @@ +// Copyright (C) 2023 johannst + +#include <type_traits> + +// (1) Primary template. +template<typename T, typename = void> +struct is_valid : std::false_type {}; + +// (2) Partial template specialization. +template<typename T> +struct is_valid<T, std::void_t<decltype(std::declval<T>().some_fun1()), + decltype(std::declval<T>().some_fun2())>> : std::true_type {}; +struct A { + void some_fun1() {} + void some_fun2() {} +}; + +struct B {}; + +static_assert(is_valid<A>::value, "is true"); +// * Compare template arg list with primary template, we only supplied one +// arg, the second one will be defaulted as +// is_valid<A, void> +// * Compare template arg list against available specializations, this will +// try to match the pattern <A, void> against the patterns defined in the +// partial specializations. +// * Try specialization (2) +// * T -> A +// * Evaluate std::void_t -> decltype's are well-formed +// std::void_t<...> -> void +// * Specialization (2) matches <A, void> +// * Pick the most specialized version -> (2) + +static_assert(!is_valid<B>::value, "is false"); +// * Compare template arg list with primary template, we only supplied one +// arg, the second one will be defaulted as +// is_valid<A, void> +// * Compare template arg list against available specializations, this will +// try to match the pattern <B, void> against the patterns defined in the +// partial specializations. +// * Try specialization (2) +// * T -> B +// * Evaluate std::void_t -> decltype's are ill-formed +// * Specialization (2) is removed from candidate set, no hard error (SFINAE) +// * No specialization matches, take the primary template. + +int main() {} |