1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
|
#include <iostream>
#include <iomanip>
#include <string>
template< typename, typename = void > struct has_size_type : std::false_type {};
template< typename T >
struct has_size_type< T, std::void_t<typename T::size_type> > : std::true_type {};
namespace bad
{
template< typename, typename = void > struct has_size_type : std::false_type {};
template< typename T >
struct has_size_type< T, typename T::size_type > : std::true_type {};
}
int main()
{
constexpr bool a = has_size_type<std::string>::value ;
// 1. name look up finds the primary template has_size_type<typename,typename>
// with template args: has_size_type< std::string, void >
// 2. look for specialisations that match has_size_type< std::string, void >
// 3. complete specialisation for has_size_type< std::string, void > : not found
// 4. look for partial specialisations that match has_size_type< std::string, void >
// 5. found partial specialisation has_size_type< T, std::void_t<typename T::size_type> >
// matches has_size_type< std::string, void >
// 6. there are no other partial specialisations; select this specialisation
static_assert( a, "error: std::string must have a nested type/type alias size_t" ) ;
constexpr bool b = bad::has_size_type<std::string>::value ;
// 1. name look up finds the primary template finds bad::has_size_type<typename,typename>
// with template args: bad::has_size_type< std::string, void >
// 2. look for specialisations that match bad::has_size_type< std::string, void >
// 3. complete specialisation for bad::has_size_type< std::string, void > : not found
// 4. look for partial specialisations that match bad::has_size_type< std::string, void >
// 5. found partial specialisation bad::has_size_type< T, typename T::size_type >
// no match: bad::has_size_type< std::string, std::string::size_type >
// does not match bad::has_size_type< std::string, void > so ignore this specialisation
// 6. there are no other partial specialisations
// 7. no matching specialisations, so select the primary template
static_assert( !b, "error: b must be false (primary template must have been selected)" ) ;
}
|