2015-06-11 3 views
4

Рассмотрим:Как преобразовать boost :: spirit :: qi :: lexeme's атрибут в std :: string?

struct s { 
    AttrType f(const std::string &); 
}; 

... и правила r с атрибутом AttrType:

template <typename Signature> using rule_t = 
    boost::spirit::qi::rule<Iterator, 
          Signature, 
          boost::spirit::qi::standard::space_type>; 

rule_t<AttrType()> r; 

r = lexeme[alnum >> +(alnum | char_('.') | char_('_'))][ 
     _val = boost::phoenix::bind(&s::f, s_inst, _1) 
    ]; 

При компиляции (с лязгом), я получаю сообщение об ошибке:

boost/phoenix/bind/detail/preprocessed/member_function_ptr_10.hpp:28:72: error: no viable conversion from 
     'boost::fusion::vector2<char, std::__1::vector<char, std::__1::allocator<char> > >' to 'const std::__1::basic_string<char>' 
       return (BOOST_PROTO_GET_POINTER(class_type, obj)->*fp)(a0); 
                     ^~ 

Мне кажется, что проблема заключается в типе переменной-заполнителя, _1. Есть ли сжатый способ преобразования lexeme 's атрибута в std::string для этой цели?

Если я вставляю дополнительное правило с типом атрибута std::string, она составляет:

rule_t<std::string()> r_str; 

r = r_str[boost::phoenix::bind(&s::f, s_inst, _1)]; 
r_str = lexeme[alnum >> +(alnum | char_('.') | char_('_'))]; 

... но это, кажется, немного неудобно. Есть ли способ лучше?

ответ

3

Вы можете использовать qi::as_string[] (что будет coerce атрибут в строку, если существует подходящее автоматическое преобразование).

В качестве альтернативы вы можете использовать qi::raw[], который предоставляет диапазон источников-итераторов. Это автоматически преобразуется в атрибуты std::string. Хорошая вещь здесь является то, что вход может быть отражено без изменения (например qi::raw[ qi::int_ >> ';' >> qi::double_ ] будет работать

В вашем случае вы, вероятно, можно использовать as_string[]. Но вы можете также установить аргумент взять std::vector<char> const&


Наконец вас мог бы использовать attr_cast<> для достижения такого же эффекта, как с отдельными qi::rule<> (но без использования отдельного правила :)), но я не рекомендую его для повышения эффективности и потому что более старые версии boost имеют ошибки в этом средстве.

+0

'as_string' похоже именно то, что я хочу. Благодаря! – Braden