I have the following code:

template<typename T, std::size_t SIZE> struct is_size_type_more_than { static constexpr bool value = sizeof(T) > SIZE; }; template<typename T, std::size_t SIZE> struct is_size_type_less_than { static constexpr bool value = sizeof(T) < SIZE; }; ... template<typename T, typename enable_if = void> class LittleEndian; using uint16le_t = LittleEndian<std::uint16_t>; using uint32le_t = LittleEndian<std::uint32_t>; using uint64le_t = LittleEndian<std::uint64_t>; using int16le_t = LittleEndian<std::int16_t>; using int32le_t = LittleEndian<std::int32_t>; using int64le_t = LittleEndian<std::int64_t>; template<typename T> class LittleEndian<T, typename std::enable_if< std::is_integral<T>::value && is_size_type_more_than<T, 1u>::value>::type> { ... }; 

But when I want to use this class, I get the following error (in fact, I would like to prohibit template instantiation for non-integer data types and for data types whose size is less than two):

 template<typename T> void some_function(T value) { LittleEndian<T> le_value = value; // Без моей метафункции все исправно работает ... } 

Mistake:

 Error C2079 'le_value' uses undefined class 'LittleEndian<T,void>' 

    2 answers 2

    "in fact, I would like to prohibit template instantiation for non-integer data types and for data types whose size is less than two" - No SFINAE is seen in this code, either the is_integral<T>::value && is_size_type_more_than or nothing. Accordingly, it is sufficient to add the corresponding check to the template body:

     template<typename T> class LittleEndian { static_assert(::std::is_integral<T>::value and (::std::size_t{1} < sizeof(T))); ... }; 

      After the declaration:

       template<typename T, typename enable_if = void> class LittleEndian; 

      when accessing LittleEndian<std::uint16_t>; instantiated, LittleEndian<std::uint16_t,void>; . At the same time, the expression inside std :: enable_if never accepts the void type, i.e. your partial class specialization will never be claimed.

      Decision:

       template<typename T, typename enable_if = typename std::enable_if< std::is_integral<T>::value && is_size_type_more_than<T, 1u>::value>::type > class LittleEndian; .... template<typename T, typename enable_if> class LittleEndian { ... }; 
      • After these actions, the construction: LittleEndian <T> le_value = value; produces error: Error C2976 'LittleEndian': too few template arguments - QuickDzen
      • @QuickDzen Probably the forward declaration, in which the default value is announced, is not visible at the point `LittleEndian <T> le_value = ...`. - Chorkov