Как определить оператор потоковой передачи для контейнера boost :: spirit :: qi и std :: list - PullRequest
1 голос
/ 13 марта 2011

В одном из моих правил есть qi :: locals <> с контейнером stl в качестве параметра.Когда я компилирую свою программу без BOOST_SPIRIT_QI_DEBUG, все работает отлично.Но когда я включаю BOOST_SPIRIT_QI_DEBUG, программа не может быть скомпилирована из-за отсутствия оператора <<. </p>

Упрощенный фрагмент:

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)

Iпопытался определить оператор потоковой передачи для TlstValues, но без эффекта.Ошибка была все та же.Мое определение оператора:

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

Может кто-нибудь посоветовать мне, как определить требуемый оператор для работы BOOST_SPIRIT_DEBUG?

Спасибо и с уважением Рик

1 Ответ

2 голосов
/ 13 марта 2011

Самый простой способ заставить 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
        }
    };
}}}
...