13

クラス内に可変個引数テンプレート関数が必要です。可変個引数のテンプレート引数は、ループのような方法で処理する必要がある文字です。だから私は、ベースケース(空のリスト)に到達するまでリストをヘッド/テールに分割して、haskellのように書くことを考えました。

例として、与えられた引数の数を数えてみましょう (最小限の例にすぎません)。

次のコードを思いつきました:

struct MyClass {
    template<char ...X>
    static int count();
};


template<>
int MyClass::count<>() {
    return 0;
}
template<char Head, char ...Tail>
int MyClass::count<Head, Tail...>() {
    return 1 + count<Tail...>();
}

ただし、これは機能しないようです:

prog.cpp:12:35: error: function template partial specialization ‘count<Head, Tail ...>’ is not allowed
prog.cpp:12:5: error: prototype for ‘int MyClass::count()’ does not match any in class ‘MyClass’
prog.cpp:3:16: error: candidate is: template<char ...X> static int MyClass::count()

どうすればこれを達成できますか?関数の部分的な特殊化がサポートされていないことは知っています。しかし、可変個引数テンプレートをヘッド/テールおよび空のベース ケース バージョンに特殊化することは、部分的な特殊化ではなく完全な特殊化だと思いましたが、間違っているのでしょうか? これを関数ではなくクラスとして記述する必要がありますか?

テンプレート構文をまったく使用せずに基本ケースを実装する例 (printf) を見つけました。しかし、 printf の呼び出しはテンプレート構文を使用せず、タイプ deductionであるため、私のケースは異なると思います。一方、私の場合、基本ケースを呼び出すときは と同じではありません。printf(tail...)printf()tailcount<>()count()

4

1 に答える 1

19

通常は、関数テンプレートを特殊化するよりもオーバーロードする方が良い考えだと思います:

struct MyClass {
    template<typename... Tail>
    static int count() {
        return 0;
    }

    template<char Head, char... Tail>
    static int count() {
        return 1 + count<Tail...>();
    }
};

#include <iostream>

int main() {
    std::cout << MyClass::count<'f','o','o'>();
}

そして、これがライブの例です。sizeof...また、組み込みの演算子をこの目的に使用できることにも言及します。

struct MyClass {
    template<char... Chars>
    static int count() {
        return sizeof...(Chars);
    //         ^^^^^^^^^
    }
};
于 2013-03-23T00:43:30.060 に答える