步骤1:将您的数据包装在一个元组中。可能是临时的。
步骤2:将您的可调用对象包装在一个函数对象中。
步骤3:编写一个tuple_foreach,对tuple的每个元素应用一个函数对象。
对于步骤1,我建议保留数据不动,只使用std :: tie创建引用的tuple。
对于步骤2,一个简单的完美转发函数对象如下:
#define RETURNS(X) ->decltype(X) { return (X); }
struct foo_functor {
template<typename... Args>
auto operator()(Args&&... args) const
RETURNS( foo( std::forward<Args>(args)... ) )
};
这段文字是关于编程的。第一段讲的是一个名为
foo
的函数覆盖集合,将其封装成一个对象,自动将任何调用分派到适当的重载
foo
函数。第二段则介绍了如何使用索引技巧在
tuple
的每个元素上运行代码。请注意保留HTML标签,不进行解释。
void do_in_order() {}
template<typename Lambda, typename... Lambdas>
void do_in_order( Lambda&& closure, Lambdas&&... closures ) {
std::forward<Lambda>(closure)();
do_in_order( std::forward<Lambdas>(closures)... );
}
template<unsigned... Is>
struct seq { typedef seq<Is> type; }
template<unsigned Max, unsigned... Is>
struct make_seq:make_seq<Max-1, Max-1, Is...> {};
template<unsigned... Is>
struct make_seq<0,Is...>:seq<Is...> {};
template<typename Tuple, typename Functor, unsigned... Is>
void foreach_tuple_helper( seq<Is...>, Tuple&& t, Functor&& f ) {
do_in_order(
[&]{ std::forward<Functor>(f)(std::get<Is>(std::forward<Tuple>(t))); }...
);
}
template<typename Tuple, typename Functor>
void foreach_tuple( Tuple&& t, Functor&& f ) {
foreach_tuple_helper( make_seq<std::tuple_size< typename std::decay<Tuple>::type >::value>(), std::forward<Tuple>(t), std::forward<Functor>(f) );
}
do_in_order
在我上次检查时在 clang 中无法使用,但是在您的编译器上工作的等效索引技巧应该很容易通过谷歌搜索获得。