0

次の積分 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))
    }
};

このような関数の停止条件をどのように書くのですか?

4

3 に答える 3

10

「関数の部分的な特殊化をシミュレートする方法」を自問するときはいつでも、「オーバーロードして、どのオーバーロードがより特殊化されているかを部分的な順序で決定する」と考えることができます。

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

于 2012-09-02T16:13:24.087 に答える
5

単純なバージョンは次のようになります。

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
于 2012-09-02T16:17:26.873 に答える
2

クラス テンプレートでメンバーを使用staticし、クラス テンプレートを特殊化するだけです。ただし、便宜上、転送関数テンプレートを作成することをお勧めします。

于 2012-09-02T15:27:50.647 に答える