Search code examples
c++templatesc++11metaprogrammingpartial-specialization

A workaround for partial specialization of function template?


Consider the following metafunction for an integral pow (it is just an example) :

class Meta
{
    template<int N, typename T> static constexpr T ipow(T x)
    {
        return (N > 0) ? (x*ipow<N-1>(x)) 
                       : ((N < 0) ? (static_cast<T>(1)/ipow<N>(x)) 
                                  : (1))
    }
};

How to write the stop condition for such a function ?


Solution

  • Anytime you ask yourself "how to simulate partial specialization for functions", you can think "overload, and let partial ordering decide what overload is more specialized".

    template<int N>
    using int_ = std::integral_constant<int, N>;
    
    class Meta
    {
        template<int N, typename T> static constexpr T ipow(T x)
        {
            return ipow<N, T>(x, int_<(N < 0) ? -1 : N>());
        }
    
        template<int N, typename T> static constexpr T ipow(T x, int_<-1>)
        {
            //                             (-N) ??
            return static_cast<T>(1) / ipow<-N>(x, int_<-N>());
        }
    
        template<int N, typename T> static constexpr T ipow(T x, int_<N>)
        {
            return x * ipow<N-1>(x, int_<N-1>());
        }
    
        template<int N, typename T> static constexpr T ipow(T x, int_<0>)
        {
            return 1;
        }
    };
    

    I think you wanted to pass -N instead of N at the comment-marked position.