9

関連している:


次の可変個引数テンプレートのペアを検討してください。

template<typename Dummy>
bool All(Param& c) {
    return true;
}

template<typename Dummy, Func* f, Func* ...rest>
bool All(Param& c) {
    return f(c) && All<Dummy, rest...>(c);
}

これは機能し、コンパイルされます。しかし、最初のテンプレート パラメータなしでどのように記述すればよいでしょうか。

些細なことに聞こえますか?まあ、それは私が思ったことです。:-) いくつかのアイデアを考えてみましょう。

アイデア #1:

template<Func* f, Func* ...rest>
bool All(Param& c) {
    return f(c) && All<rest...>(c);
}
template<>
bool All(Param& c) {
    return true;
}

うまくいかない...これを試みたとき、私は専門化を念頭に置いていましたが、2番目の考えでは、それがどのように機能するかではありません。

元の例では、オーバーロードの 2 つの異なるテンプレートを作成しました。最初は 1 つのテンプレート パラメーターを取り、2 つ目は 2 つ以上を取ります。あいまいさも専門性も関係ありません。私はそれを正しく理解していますか?

アイデア #2:

bool All(Param& c) {
    return true;
}

template<Func* f, Func* ...rest>
bool All(Param& c) {
    return f(c) && All<rest...>(c);
}

空であることは非テンプレート関数の呼び出しに展開されないため、明らかに機能All<rest...>しません。rest...

アイデア #3:

ソリューションを少し再構築しましょう。

template<Func* f>
bool All(Param& c) {
    return f(c);
}

template<Func* f, Func* ...rest>
bool All(Param& c) {
    return f(c) && All<rest...>(c);
}

All(c) はあいまいになるため、これは使用できません。したがって、引数が 0 の場合と引数が 0 より大きい場合が必要です... または、引数が 1 の場合と引数が 1 より大きい場合はどうでしょうか。

アイデア #3.5:

template<Func* f>
bool All(Param& c) {
    return f(c);
}

template<Func* f, Func* f2, Func* ...rest>
bool All(Param& c) {
    return f(c) && All<f2, rest...>(c);
}

うん、動作しますが、コピーパスタが含まれています (この場合は単純ですが、より大きくなる可能性があります!)。ちょうど別の回避策。

アイデア #4:

#1 を試してみましょう。ただし、関数の代わりにクラスを使用します。

template<Func* f, Func* ...rest>
struct All {
    static bool func(Param& c) {
        return f(c) && All<rest...>(c);
    }
};
template<>
struct All {
    static bool func(Param& c) {
        return true;
    }
};

クラスを専門化できるので、これは有望に見えます。でもねえ、それは何ですか?

申し訳ありませんが、実装されていません: 'rest ...' を固定長の引数リストに展開することはできません

これは GCC 4.4 のものではありませんか? 私は MinGW GCC 4.6.1 (tdm-1) を使用しています。


とにかく、そんな初歩的なことを素直にできないと思っていいのだろうか。このタスクを実行するには、ダミー テンプレート パラメータを追加して回避策を使用する必要がありますか?

または、ゼロ引数のケースを指定するための単純で正しいバリアントがありますか?

4

2 に答える 2

3

今回の質問の場合、テンプレート引数は非型なので、以下のようにデフォルトのテンプレート引数を持つ関数を用意すれば、引数をDummy保存できます。

template<typename = void>
bool All(Param& c) {
    return true;
}

template<Func* f, Func* ...rest>
bool All(Param& c) {
    return f(c) && All<rest...>(c);
}

ただし、これが常に当てはまるかどうかはわかりません。より一般的な場合、std::enable_ifまたは同様のディスパッチが必要になる場合があります (ただし、これによりコードが少し長くなります)。

于 2011-11-02T18:30:13.460 に答える
1

あなたの質問は次のようなものです: Recursive Variadic Template Function のコンパイル エラー

うまくいくはずの答えが2つあります。1 つはあなたの #3.5 で、もう 1 つは持っていなかったものです。

于 2011-11-02T03:47:42.530 に答える