8

これは、この素晴らしい知識の交換に関する私の最初の質問であり、何らかの助けが得られることを願っています.

PrintTo 関数を作成する一般的な方法を実装しようとしています (後で GoogleTest で使用されます)。

したがって、次のコードは仕事の半分だけを行います。定義された構造体の値のみを出力しますFoo::Bar

#include <iostream>
#include <sstream>
#include <string>

#include <boost/fusion/container.hpp>
#include <boost/fusion/algorithm.hpp>
#include <boost/fusion/adapted/struct/define_assoc_struct.hpp>
#include <boost/fusion/include/define_assoc_struct.hpp>

namespace Foo
{
  namespace Keys
  {
    struct StringField;
    struct IntField;
  };
}

BOOST_FUSION_DEFINE_ASSOC_STRUCT(
  (Foo), Bar,
  (std::string, stringField, Foo::Keys::StringField)
  (int,         intField,    Foo::Keys::IntField))


struct fusion_printer_impl
{
  std::ostream& _os;

  fusion_printer_impl(std::ostream& os) 
    : _os(os) {}

  template <typename T>
  void operator() (T& v) const
  {
    _os << v << std::endl;
  }
};

void PrintTo(Foo::Bar const& v, std::ostream* os)
{
  boost::fusion::for_each(v, fusion_printer_impl(*os));
}

int main()
{
  Foo::Bar fb("Don't panic!", 42);
  std::ostringstream temp;

  PrintTo(fb, &temp);

  std::cout << temp.str() << std::endl;
}

だから私が探しているのは、自動的に印刷する方法Foo::Keysです。BOOST_FUSION_DEFINE_ASSOC_STRUCT のマクロ生成コードを調べたところ、キーが static const char* boost::fusion::extension::struct_member_name::call() として利用できることがわかりました。

fusion::for_each のコードを調べたところ、コード全体を「複製」して、fusion_printer_impl::operator() がキーと値の 2 つのパラメータで呼び出されるようにする方法しかありませんでした。その方向に進む前に、これを達成するためのより簡単な方法があるかどうかを知りたい.

boost::fusion::map を明示的に定義できることはわかっています。ここでは、fusion::pair を介してキーのタイプと値に自動的にアクセスします。しかし、これは現在私にとって選択肢ではありません。

したがって、ここでの助けは大歓迎です。

4

1 に答える 1

3

あなたの質問は良い質問です。うまくいけば、ここの誰かがこれよりもきれいなものに到達するでしょう:

...
struct fusion_printer_2
{
    typedef std::ostream* result_type;

    // Well, not really the intented use but...
    template<typename T>
    std::ostream* operator()(std::ostream const* out, const T& t) const
    {
        std::ostream* const_violated_out = const_cast<result_type>(out);
        (*const_violated_out) << 
            (std::string( typeid( typename boost::fusion::result_of::key_of<T>::type ).name() ) + ": " + boost::lexical_cast<std::string>(deref(t))) << std::endl;
        return const_violated_out;
    }
};

void PrintTo(Foo::Bar const& v, std::ostream* os)
{
  boost::fusion::iter_fold(v, os, fusion_printer_2());
}
...
于 2013-04-30T14:05:11.247 に答える