C++ 如何在boost::fusion关联结构上迭代,并以通用方式访问键

C++ 如何在boost::fusion关联结构上迭代,并以通用方式访问键,c++,boost,boost-fusion,C++,Boost,Boost Fusion,这是我在这次伟大的知识交流中提出的第一个问题,我希望能找到一些帮助 我尝试实现一种创建PrintTo函数的通用方法(稍后将在GoogleTest中使用) 所以下面的代码只完成了一半的工作。它只打印已定义结构的值Foo::Bar #include <iostream> #include <sstream> #include <string> #include <boost/fusion/container.hpp> #include <boo

这是我在这次伟大的知识交流中提出的第一个问题,我希望能找到一些帮助

我尝试实现一种创建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
{
命名空间键
{
StringField结构;
结构域;
};
}
增强\融合\定义\关联\结构(
(Foo),Bar,,
(std::string、stringField、Foo::Keys::stringField)
(int,intField,Foo::Keys::intField))
结构融合\u打印机\u导入
{
std::ostream和os;
fusion_printer_impl(标准::ostream&os)
:_os(os){}
模板
无效运算符()(T&v)常量
{

_os你的问题很好,希望这里有人能想出比这更干净的办法:

...
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());
}
...
。。。
结构融合打印机2
{
typedef std::ostream*结果类型;
//嗯,不是真正的预期用途,但是。。。
模板
std::ostream*运算符()(std::ostream const*out,const T&T)const
{
std::ostream*const_违犯(out)=const_cast(out);;

(*const_违反_out)谢谢你的回答。这对我帮助很大。通过将函子的结果类型更改为std::string,并将boost::fusion::iter_fold的结果直接流到*os,我可以避免难看的const_cast。更不用说了,让某人的灵魂被深不可测的抽象和可怕的编译器错误压碎这将是非常不人道的……我知道你在说什么。至少VC10和Clang有了很大的改进。(我不知道gcc)。在使用boost::spirit时出错总是很有趣的:-(