5

与えられたテンプレート

template <int n>
void f(){...};

次のようにすることで、特定の値に特化できることを知っnています。

template <>
void f<2>(){...};

しかし、私がそれをすべてのポジティブに特化することを可能にする方法はありますnか?

私は次のことを考えました

template <int n>
void f<n>(){
    int dummy[n]; //invalid for n < 0
    ...
};

したがって、n<0このコードは無効であり、コンパイラは前の定義に頼ります。残念ながら、私が得るのはredefinition of 'void f<n>()'エラーだけです。

注:これはおそらく標準ではサポートされていないと思います。この効果を達成するための方法(おそらくテンプレートメタプログラミング)がないかどうかを尋ねています。

4

1 に答える 1

13

1 つのオプションは、別のレベルの間接化を使用することです。数値と が負かどうかを表すnaの 2 つの引数を取る補助テンプレートを定義し、そのテンプレートを が負の場合に特殊化します。次に、関数で適切な引数を使用してテンプレートをインスタンス化します。boolnnf

例えば:

template <int n, bool isNegative> struct fImpl {
    static void f() {
       /* ... code for when n is positive ... */
    }
};
template <int n> struct fImpl<n, true> {
    static void f() {
       /* ... code for when n is negative ... */
    }
};

template <int n> void f() {
    fImpl<n, (n < 0)>::f();
}

もう 1 つのオプションは、SFINAE オーバーロードstd::enable_ifC++11 (または Boost の同等物) のテンプレート クラスを使用することです。

template <int n> void f(typename std::enable_if<(n < 0)>::type* = 0) {
    /* ... n is negative ... */
}

template <int n> void f(typename std::enable_if<(n >= 0)>::type* = 0) {
    /* ... n is positive ... */
}

これらの各関数nは、適切な符号がある場合にのみオーバーロードの解決に使用できるため、正しいバージョンが常に呼び出されます。

お役に立てれば!

于 2012-04-04T19:13:08.113 に答える