以下增强代码是否可以转换为纯c ++ 11标准库?
我看到std::tuple
和std::for_each
,但我似乎无法让他们互相玩耍。
我目前正在使用gcc 4.7.2。
CODE
#include <string>
#include <algorithm>
#include <iostream>
#include <boost/fusion/algorithm/iteration/for_each.hpp>
#include <boost/fusion/include/boost_tuple.hpp>
struct DoOutput
{
template<typename T>
void operator()(T const& t) const
{
std::cerr << t << std::endl;
}
void operator()(std::string const& t) const
{
std::cerr << "'" << t << "'" << std::endl;
}
};
int
main( int argc, char* argv[] )
{
boost::tuple< std::string, int > t = boost::make_tuple( "foo", 42 );
boost::fusion::for_each( t, DoOutput() );
return 0;
}
答案 0 :(得分:4)
不,代码不能直接兑换。
Boost.Fusion是一个用于处理元组的库,因此它的for_each
与元组一起工作,即具有零个或多个异构类型的结构。 std::for_each
适用于迭代器范围,它是同类型值的范围。
使用类似index_tuple.h的内容,您可以将其更改为:
struct sink {
template<typename... T>
sink(T&&...) { }
};
template<typename T, typename F>
int apply(T&& t, F& f)
{
f(std::forward<T>(t));
return 0;
}
template<typename Tuple, typename F, unsigned... Indices>
void apply(Tuple&& t, F&& f, index_tuple<Indices...>)
{
sink{ apply(std::get<Indices>(std::forward<Tuple>(t)), f)... };
}
int main()
{
std::tuple< std::string, int > t = std::make_tuple( "foo", 42 );
apply(t, DoOutput(), make_index_tuple<std::tuple_size<decltype(t)>::value>::type() );
}
这会创建一个index_tuple<0,1>
类型,并调用apply
,将参数包Indices
推导为{0, 1}
,然后将该包扩展为:
sink{ apply(std::get<0>(t), f), apply(std::get<1>(t), f) };
其中f
是DoOutput
类型的函数对象,每个都应用调用f(tn)
仅需要初始化临时sink
,因为您无法在表达式中展开参数包,例如这是无效的:
f(std::get<Indices>(t))...;
因此,将包作为初始化列表扩展为对象的构造函数,这也保证了包扩展的每个元素按顺序进行评估。
答案 1 :(得分:1)
没有。 C ++ 11标准库不包含boost::fusion
的功能。您可以期待的最好方法是调整std::tuple
以使用boost::fusion
:
#include <string>
#include <algorithm>
#include <iostream>
#include <tuple>
#include <boost/fusion/algorithm/iteration/for_each.hpp>
#include <boost/fusion/adapted/std_tuple.hpp> //This feature is undocumented
struct DoOutput
{
template<typename T>
void operator()(T const& t) const
{
std::cerr << t << std::endl;
}
void operator()(std::string const& t) const
{
std::cerr << "'" << t << "'" << std::endl;
}
};
int
main( int argc, char* argv[] )
{
std::tuple< std::string, int > t = std::make_tuple( "foo", 42 );
boost::fusion::for_each( t, DoOutput() );
return 0;
}