問題
任意の数のファンクター オブジェクト、またはより一般的には呼び出し可能なオブジェクト (異なる型) を受け入れ、それらを内部データ構造に適用する関数を作成したいと考えています。この関数は、コード内のさまざまなポイントでさまざまな数のファンクターと共に使用されます。
1,2,3...などを受け入れるために別のバージョンを作成してコードを複製するのではなく、可変個引数テンプレートを使用することを考えました。
特にこれについてGoogleで何も見つけることができず、他の人が役立つと思うかもしれないので、回答として以下に投稿する解決策を見つけました。しかし、誰かがより良いアイデアを持っている場合は、投稿してください。これを行う標準的な方法があるはずだと感じていますか?
素朴な試み
これがうまくいかないことはわかっていましたが、最初の試みは
#include <iostream>
using namespace std;
struct FunctorA {
void operator() () {
cout << "FunctorA" << endl;
}
};
struct FunctorB {
void operator() () {
cout << "FunctorB" << endl;
}
};
template<typename... Fs>
void apply_functors(Fs... fs) {
fs()...; // will not work - can only expand packs in certain situations (e.g. as funciton
}
int main(void) {
apply_functors(FunctorA(),FunctorB());
apply_functors(FunctorA());
apply_functors([]()->void{ cout << "Lambda" << endl; });
return 0;
}
ただし、特定の状況でのみパラメーター パックを拡張することが許可されており、このような無料のものはないため、これは機能しません。
試行 2
私の次のアイデアは、ファンクターをパラメーターとして渡して展開することしかできないダミー関数を作成することでした。この背後にある理由は、関数パラメーターは、パラメーター パックを拡張できる状況の 1 つだからです。
template<typename... Fs>
void _dummyF_impl(Fs... fs){}
template<typename... Fs>
void apply_functors(Fs... fs) {
_dummyF_impl( fs()... ); // only works if all functors return a value (else we get "invalid use of 'void'")
}
ただし、ファンクターはoperator()
s から void を返し、void をパラメーターとして関数に渡すことができないため、これは機能しません。