// #5, enabled via a type template parameter template<classT, typename = std::enable_if_t<std::is_array<T>::value>> voiddestroy(T* t) // note: function signature is unmodified { for (std::size_t i = 0; i < std::extent<T>::value; ++i) destroy((*t)[i]); }
/* template<class T, typename = std::enable_if_t<std::is_void<T>::value>> void destroy(T* t) {} // error: has the same signature with #5 */
// the partial specialization of A is enabled via a template parameter template<classT, classEnable = void> class A {}; // primary template
template<classT> classA<T, typename std::enable_if<std::is_floating_point<T>::value>::type> {}; // specialization for floating point types
intmain() { union { int i; char s[sizeof(std::string)]; } u;
A<int>{}; // OK: matches the primary template A<double>{}; // OK: matches the partial specialization }
Output:
1 2 3 4
default constructing trivially default constructible T destroying trivially destructible T constructing T with operation destroying non-trivially destructible T