Я обновляю старый код, который работал в более старых (~ 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>
без семантического действия код компилирует и отладка правила состояния показывает ожидаемые результаты. Что мне нужно сделать, чтобы правильно инициализировать структуру?
Я согласен, что это выглядит как регрессия, вы можете сообщить об этом сопровождающим в списке рассылки [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)
¹ (я думаю, что это было введено, чтобы дать некоторым людям возможность, которую вообще нельзя было включить, потому что это сломало бы существующий код)
Других решений пока нет …