Identifying primitive types in templates

后端 未结 8 850
南旧
南旧 2020-11-27 17:40

I am looking for a way to identify primitives types in a template class definition.

I mean, having this class :

template
class A{
void         


        
8条回答
  •  旧巷少年郎
    2020-11-27 18:34

    There is a better way - using SFINAE. With SFINAE you don't have to list out every primitive type. SFINAE is a technique that depends on the idea that when template specialization fails it falls back to a more general template. ( it stands for "Specialization failure is not an error" ).

    Also you don't really define if you consider a pointer to be a primitive type, so I'll make you templates for all the combinations.

    // takes a pointer type and returns the base type for the pointer.
    // Non-pointer types evaluate to void.
    template < typename T > struct DePtr                       { typedef void R; }; 
    template < typename T > struct DePtr< T * >                { typedef T R; };
    template < typename T > struct DePtr< T * const >          { typedef T R; };
    template < typename T > struct DePtr< T * volatile >       { typedef T R; };
    template < typename T > struct DePtr< T * const volatile > { typedef T R; };
    
    // ::value == true if T is a pointer type
    template < class T > struct IsPointer                        { enum { value = false }; };
    template < class T > struct IsPointer < T *                > { enum { value = true };  };
    template < class T > struct IsPointer < T * const          > { enum { value = true };  };
    template < class T > struct IsPointer < T * volatile       > { enum { value = true };  };
    template < class T > struct IsPointer < T * const volatile > { enum { value = true };  };
    
    // ::value == true if T is a class type. ( class pointer == false )
    template < class T > struct IsClass 
    {
       typedef u8 yes; typedef u16 no; 
       template < class C >    static yes isClass( int C::* );
       template < typename C > static no  isClass( ... );
       enum { value = sizeof( isClass( 0 )) == sizeof( yes ) };
    };
    
    // ::value == true if T* is a class type. ( class == false )
    template < class T > struct IsClassPtr 
    {
       typedef u8 yes; typedef u16 no; 
       template < class C >    static yes isClass( int C::* );
       template < typename C > static no  isClass( ... );
       enum { value = sizeof( isClass< typename DePtr< T >::R >( 0 )) == sizeof( yes ) };
    };
    
    // ::value == true if T is a class or any pointer type - including class and non-class pointers.
    template < class T > struct IsClassOrPtr : public IsClass { };
    template < class T > struct IsClassOrPtr < T *                > { enum { value = true };  };
    template < class T > struct IsClassOrPtr < T * const          > { enum { value = true };  };
    template < class T > struct IsClassOrPtr < T * volatile       > { enum { value = true };  };
    template < class T > struct IsClassOrPtr < T * const volatile > { enum { value = true };  };
    
    
    template < class T > struct IsClassOrClassPtr : public IsClass { };
    template < class T > struct IsClassOrClassPtr < T *                > : public IsClassPtr< T*                > { };
    template < class T > struct IsClassOrClassPtr < T * const          > : public IsClassPtr< T* const          > { };
    template < class T > struct IsClassOrClassPtr < T * volatile       > : public IsClassPtr< T* volatile       > { };
    template < class T > struct IsClassOrClassPtr < T * const volatile > : public IsClassPtr< T* const volatile > { };
    

提交回复
热议问题