Template specialization for multiple types

前端 未结 2 946
日久生厌
日久生厌 2021-02-05 17:13

Title is a little ambiguous.

Lets say I have a template defined as:

template < typename T >
void foo ( int x ) ;
template <>
void foo

        
相关标签:
2条回答
  • 2021-02-05 17:34

    One possibility is to specialize a class template for multiple types at once:

    // from: http://en.cppreference.com/w/cpp/types/enable_if
        template<bool B, class T = void>
        struct enable_if {};
    
        template<class T>
        struct enable_if<true, T> { typedef T type; };
    
    template < typename A, typename B >
    struct is_same
    {
        static const bool value = false;
    };
    template < typename A >
    struct is_same<A, A>
    {
        static const bool value = true;
    };
    
    
    template < typename T, typename dummy = T >
    struct remap;
    
    template < typename T >
    struct remap
    <
        T,
        typename enable_if<    is_same<T, unsigned char>::value
                            || is_same<T, signed char>::value, T >::type
    >
    {
        void foo(int);
    };
    
    
    int main()
    {
        remap<signed char> s;
        s.foo(42);
    }
    

    Another possibility is to specialize a class template for categories of types (type traits):

    #include <cstddef>
    
    template < typename T >
    struct is_integer
    {
        static const bool value = false;
    };
    template<> struct is_integer<signed char> { static const bool value = true; };
    template<> struct is_integer<unsigned char> { static const bool value = true; };
    
    
    template < typename T, typename dummy = T, std::size_t S = sizeof(T) >
    struct remap;
    
    template < typename T >
    struct remap
    <
        T
        , typename enable_if<is_integer<T>::value, T>::type
        , 1 // assuming your byte has 8 bits
    >
    {
        void foo(int);
    };
    
    
    int main()
    {
        remap<signed char> s;
        s.foo(42);
    }
    
    0 讨论(0)
  • 2021-02-05 17:47

    You need your remap trait to simply map from input types to output types, and have your foo<T>(int) interface function delegate to a foo_implementation<remap<T>::type>(int) implementation. i.e.:

    template <typename T>
    struct remap {
        // Default: Output type is the same as input type.
        typedef T type;
    };
    
    template <>
    struct remap<char> {
        typedef unsigned char type;
    };
    
    template <>
    struct remap<signed char> {
        typedef unsigned char type;
    };
    
    template <typename T>
    void foo_impl(int x);
    
    template <>
    void foo_impl<unsigned char>(int x) {
        std::cout << "foo_impl<unsigned char>(" << x << ") called\n";
    }
    
    template <typename T>
    void foo(int x) {
        foo_impl<typename remap<T>::type>(x);
    }
    

    See it live at ideone.com.

    That said, it might be realistically simpler to define foo_char, foo_int and foo_short and just call the correct one from client code. foo<X>() isn't syntactically much different from foo_X().

    0 讨论(0)
提交回复
热议问题