如何为boost :: spirit :: qi和std :: list容器定义流操作符

时间:2011-03-13 01:00:45

标签: boost-spirit boost-spirit-qi

在我的一条规则中,有一个qi :: locals<>使用stl容器作为参数。当我编译没有BOOST_SPIRIT_QI_DEBUG的程序时,一切正常。但是当我打开BOOST_SPIRIT_QI_DEBUG时,由于缺少运算符而无法编译程序<<。

简化代码段:

typedef std::list< int > TlstValues;

template <typename Iterator, typename Skipper>
struct G_test : qi::grammar<Iterator, Skipper>
{
  ...
  G_test() : G_test::base_type(rule_test)
  {
    ...
    BOOST_SPIRIT_DEBUG_NODE(rule_test);
  }

  qi::rule<Iterator, qi::locals<TlstValues>, Skipper> rule_test;
}

错误:

error C2679: binary '<<' : no operator found which takes a right-hand operand of type 'TlstExpressionItems' (or there is no acceptable conversion)

我尝试为TlstValues定义流操作符但没有效果。错误仍然是一样的。我的运营商定义:

std::ostream& operator << (std::ostream& os, TlstValues & z)
{
return os;
} 

有人可以告诉我如何定义所需的操作符以使BOOST_SPIRIT_DEBUG工作吗?

谢谢和问候 瑞克

1 个答案:

答案 0 :(得分:2)

强制ADL查找流媒体运营商的最简单方法是将其放入名称空间std:

namespace std
{
    std::ostream& operator<< (std::ostream& os, TlstValues& z)
    {
        // do your stuff here
        return os;
    } 
}

是的,我知道,这是正式不允许的。但是,从务实的角度来看,这仍然是最简单的方法。

符合标准的解决方案是为您的属性类型专门化Spirit定制点print_attribute_debug

// your specialization needs to be in namespace boost::spirit::traits
namespace boost { namespace spirit { namespace traits
{
    template <typename Out>
    struct print_attribute_debug<Out, TlstValues>
    {
        static void call(Out& out, TlstValues const& val)
        {
            // do your output here; Out is a std::ostream
        }
    };
}}}