3

次のブースト コードは純粋な 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;
}
4

2 に答える 2

4

いいえ、コードは直接変換できません。

Boost.Fusion はタプルを操作するためのライブラリであるため、for_eachタプル、つまり 0 個以上の異種の型を持つ構造体で機能します。 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あり、それぞれの apply 呼び出しf(tn)

sink式でパラメーターパックを展開できないため、一時的なものを初期化する必要があります。たとえば、これは無効です。

    f(std::get<Indices>(t))...;

その代わりに、パックは初期化子リストとしてオブジェクトのコンストラクターに展開されます。これにより、パック展開の各要素が順番に評価されることも保証されます。

于 2012-12-20T15:42:10.367 に答える
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;
}
于 2012-12-20T15:43:34.853 に答える