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

发布于 2024-10-21 19:26:18 字数 956 浏览 8 评论 0原文

在我的规则之一中有 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 工作吗?

感谢和问候 瑞克

In one of my rules a have qi::locals<> with stl container as parameter. When I compile my program without BOOST_SPIRIT_QI_DEBUG, everything works fine. But when I turn BOOST_SPIRIT_QI_DEBUG on, program can't be compiled because of missing operator <<.

Simplified snippet:

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:

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

I tried to define streaming operator for TlstValues but without effect. Error was still the same. My operator definition:

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

Can someone please advise me how to define required operator to make BOOST_SPIRIT_DEBUG work?

Thanks and regards
Rick

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

坏尐絯 2024-10-28 19:26:18

强制 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
        }
    };
}}}

The simplest way to force ADL to find your streaming operator is to put it into the namespace std:

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

Yes, I know, this is formally not allowed. However, from a pragmatic standpoint it's still the easiest way.

The Standards conformant solution is to specialize the Spirit customization point print_attribute_debug for your attribute type:

// 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
        }
    };
}}}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文