函数模板部分专用化的解决方法

A workaround for partial specialization of function template?

本文关键字:解决 方法 专用 函数模板部      更新时间:2023-10-16

考虑积分pow的以下元函数(这只是一个例子):

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))
    }
};

如何编写这样一个函数的停止条件?

每当你问自己"如何模拟函数的部分专业化"时,你可以考虑"重载,让部分排序决定什么重载更专业化"。

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;
    }
};

我想您想在注释标记的位置传递-N而不是N

一个简单的版本可能是这样的:

template <typename T, unsigned int N> struct pow_class
{
    static constexpr T power(T n) { return n * pow_class<T, N - 1>::power(n); }
};
template <typename T> struct pow_class<T, 0>
{
    static constexpr T power(T) { return 1; }
};
template <unsigned int N, typename T> constexpr T static_power(T n)
{
    return pow_class<T, N>::power(n);
}

用法:

auto p = static_power<5>(2);  // 32

只需在类模板中使用static成员并专门化类模板。不过,为了方便起见,您可能需要创建一个转发函数模板。