这是一个从Luc Touraille 的回答中受到高度启发的替代解决方案。
这个版本是使用Metafunction 类而不是函数来完成的,它允许在static_for_each
函数范围之外调用 (如果工作必须在编译时完全完成,所以在运行时没有调用不必要的函数时很有用)。
此外,由于first
和last
typedef,它提供了更多的交互,允许在必要时从循环中获取信息,有点像 areturn
为函数工作的方式。
Previous
由于传递给元函数类的第二个模板参数,您还可以在每次迭代中访问上一次迭代结果F
。
最后,您可以使用模板参数向循环过程提供数据Initial
,它将作为Previous
第一次迭代的参数值给出。
# include <boost/mpl/begin_end.hpp>
# include <boost/mpl/next_prior.hpp>
# include <boost/mpl/apply.hpp>
namespace detail_static_for_each
{
// Loop
template<typename Begin, typename End, typename F, typename Previous>
struct static_for_each
{
private:
typedef typename Begin::type current_type;
public:
typedef typename boost::mpl::apply<F, current_type, Previous>::type first;
typedef typename static_for_each<typename boost::mpl::next<Begin>::type, End, F, first>::last last;
};
// End of loop
template<typename End, typename F, typename Last>
struct static_for_each<End, End, F, Last>
{
public:
typedef Last first;
typedef Last last;
};
} // namespace detail_static_for_each
// Public interface
template<typename Sequence, typename F, typename Initial = void>
struct static_for_each
{
private:
typedef typename boost::mpl::begin<Sequence>::type begin;
typedef typename boost::mpl::end<Sequence>::type end;
typedef typename detail_static_for_each::static_for_each<begin, end, F, Initial> loop;
public:
typedef typename loop::first first;
typedef typename loop::last last;
};
这是一个提供和检索数据的简单示例:
# include <iostream>
# include <boost/type_traits/is_same.hpp>
# include <boost/mpl/if.hpp>
# include <boost/mpl/vector.hpp>
# include "static_for_each.hpp"
struct is_there_a_float
{
template<typename currentItem, typename PreviousIterationType>
struct apply
{
typedef typename boost::mpl::if_< PreviousIterationType,
PreviousIterationType,
boost::is_same<float, currentItem> >::type type;
};
};
struct test
{
typedef boost::mpl::vector< char, long, long, double, float, int, char > sequence;
typedef static_for_each<sequence, is_there_a_float, boost::false_type>::last found;
};
int main(void)
{
std::cout << std::boolalpha << test::found::value << std::endl;
return (0);
}
这些特性使得使用static_for_each
更类似于使用常见的运行时循环(while
, for
, BOOST_FOREACH ...),因为您可以更直接地与循环交互。