Boost.Fusionには、fusedという関数オブジェクトのアダプタがあり、
fusedによってアダプトされた関数オブジェクトには、Fusionのシーケンスによって引数指定できる機能が付加されます。
#include <functional> #include <boost/assert.hpp> #include <boost/fusion/include/make_vector.hpp> #include <boost/fusion/include/fused.hpp> namespace fusion = boost::fusion; int main() { fusion::fused<std::plus<int> > f; BOOST_ASSERT(f(fusion::make_vector(1, 2)) == 3); }
make_fused()というヘルパ関数もあります。
#include <functional> #include <boost/assert.hpp> #include <boost/fusion/include/make_vector.hpp> #include <boost/fusion/include/make_fused.hpp> namespace fusion = boost::fusion; int main() { BOOST_ASSERT(fusion::make_fused(std::plus<int>())(fusion::make_vector(1, 2)) == 3); }
これがあると、関数の引数を一旦タプルとしてメンバ変数に保持し、その後関数適用の際にタプルが展開できないから引数として渡せないという問題を解消することができそうです。
FusionがまだVariadic Templatesに正式対応していないため、コンパイルは通していませんが、以下のように書けるはずです。
template <class... Args> class X { std::tuple<Args...> args_; public: X(Args&&... args) : args_(std::forward<Args>(args)...) {} template <class F> void apply(F&& f) const { fusion::make_fused(f)(args_); } };
関連エントリ:
可変引数はラムダ式でコピーキャプチャできない(主にコメント欄)
参照: