передача анализируемой структуры в функцию с помощью phoenix :: bind

Я обновляю старый код, который работал в более старых (~ 1,38 или около того) версиях boost. Я обновил до 1.63 и не могу понять, как заставить старую версию скомпилировать.

Это соответствующие части

void print (StateStruct const& ss)
{
std::cout << ss.Name;
}

struct StateStruct
{
std::string Name;
float avalue;
}

BOOST_FUSION_ADAPT_STRUCT (
StateStruct,
(std::string, NAME)
(float, avalue)
)

и правило парсера, которое раньше работало

state %=
( qi::lexeme[qi::char_(a-zA-Z) >> +qi::char("-a-zA-Z0-9_")]
>> qi::float_
)
[phoenix::bind(&print, qi::_val)]
;

qi::rule (Iterator, StateStruct(), skipper_type) state;

С g ++ 6.3.0 и boost 1.63 я получаю сообщение об ошибке в соответствии с

неверная инициализация типа const StateStruct::StateStruct& из выражения типа boost::fusion::vector<boost::fusion::vector<char, std::vector<char, std::allocator<char> > >, float>

без семантического действия код компилирует и отладка правила состояния показывает ожидаемые результаты. Что мне нужно сделать, чтобы правильно инициализировать структуру?

3

Решение

Я согласен, что это выглядит как регрессия, вы можете сообщить об этом сопровождающим в списке рассылки [spirit-general].

В догадках я вспомнил неясное определение, которое было введено как своего рода хак совместимости ». И вот, вещь компилируется с BOOST_SPIRIT_ACTIONS_ALLOW_ATTR_COMPAT определены:

Жить на Колиру:

#define BOOST_SPIRIT_ACTIONS_ALLOW_ATTR_COMPAT
#include <boost/fusion/adapted/struct.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>

struct StateStruct { std::string Name; float avalue; };

BOOST_FUSION_ADAPT_STRUCT(StateStruct, Name, avalue)

void print(StateStruct const& ss) { std::cout << "print: " << ss.Name << "\n"; }

namespace qi = boost::spirit::qi;
namespace px = boost::phoenix;

int main() {
using Iterator = std::string::const_iterator;
using skipper_type = qi::space_type;
qi::rule<Iterator, StateStruct(), skipper_type> state;

state %=
( qi::as_string [ qi::lexeme[qi::char_("a-zA-Z") >> +qi::char_("-a-zA-Z0-9_")] ] >> qi::float_
)
[ px::bind(&print, qi::_val) ]
;

std::string const input("identifier31415 3.1415");
Iterator f = input.begin(), l = input.end();
StateStruct parsed;
bool ok = qi::phrase_parse(f, l, state, qi::space, parsed);

if (ok)
std::cout << "Parsed: " << boost::fusion::as_vector(parsed) << "\n";
else
std::cout << "Parse failed\n";

if (f != l)
std::cout << "Remaining unparsed input: '" << std::string(f,l) << "'\n";
}

Печать:

print: identifier31415
Parsed: (identifier31415 3.1415)

¹ (я думаю, что это было введено, чтобы дать некоторым людям возможность, которую вообще нельзя было включить, потому что это сломало бы существующий код)

2

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector