这个boost::元组代码可以转换为纯std::标准库代码吗?

is this boost::tuple code convertible to pure std:: standard library code?

本文关键字:代码 标准 std 转换 元组 boost 这个      更新时间:2023-10-16

以下boost代码可转换为纯c++11标准库吗?

我看到了std::tuplestd::for_each,但我似乎不能让他们互相玩。

我现在使用的是gcc 4.7.2。

#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;
}

不可以,代码不能直接转换。

提振。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))...;

因此,将包扩展为对象构造函数的初始化列表,这也保证了包扩展的每个元素都按顺序求值。

No。c++ 11标准库不包括boost::fusion的功能。您所能期望的最好结果是使std::tupleboost::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;
}