Используя boost :: phoenix :: bind вместе с boost :: spirit :: qi :: symbols :: add

Я хочу проанализировать число с плавающей запятой в текстовом файле и вставить его в таблицу символов; синтаксический анализатор и таблица символов предоставляются spirit :: qi.

Вот мой код:

#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>

#include <stdint.h>
#include <iostream>
#include <string>
template<typename VTYPE>
struct VTable : boost::spirit::qi::symbols<char, VTYPE> {
VTable() {} // empty
};

int main() {
using boost::spirit::qi::_1;
using boost::spirit::qi::eps;
using boost::spirit::qi::rule;
using boost::spirit::qi::ascii::space;
using boost::spirit::qi::space_type;
using boost::spirit::qi::real_parser;
using boost::spirit::qi::int_parser;
using boost::spirit::qi::strict_real_policies;
VTable<double> floatDecs;
floatDecs.add("hallo", 15.26)("duDa", 18.5);

const std::string some = "some";
rule<std::string::iterator, double> value = real_parser<double, strict_real_policies<double>>() [ boost::phoenix::bind(&VTable<double>::add, floatDecs, boost::phoenix::cref(some), _1) ];

std::cout << boost::spirit::qi::phrase_parse(test.begin(), test.end(), value, space);
return 0;
}

Проблема здесь заключается в boost :: phoenix :: bind, но я не знаю, как это исправить (я довольно новичок в этой библиотеке).

2

Решение

Вот рабочая версия. После я перечислю, что с тобой не так.

#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>

#include <stdint.h>
#include <iostream>
#include <string>
template<typename VTYPE>
struct VTable : boost::spirit::qi::symbols<char, VTYPE> {
VTable() {} // empty
};

int main() {
using boost::spirit::qi::_1;
using boost::spirit::qi::eps;
using boost::spirit::qi::rule;
using boost::spirit::qi::ascii::space;
using boost::spirit::qi::space_type;
using boost::spirit::qi::real_parser;
using boost::spirit::qi::int_parser;
using boost::spirit::qi::strict_real_policies;

VTable<double> floatDecs;
floatDecs.add("hallo", 15.26)("duDa", 18.5);

const char some[] = "some";

rule<std::string::iterator, double()> value =
real_parser<double, strict_real_policies<double> >()
[ boost::phoenix::bind(floatDecs.add, boost::phoenix::val(some), _1) ];

std::string test("10.6");

std::string::iterator b(test.begin()), e(test.end());

std::cout << boost::spirit::qi::phrase_parse(b, e, value, space);

return 0;
}

Во-первых, необходимо исправить переменную, которую вы хотите использовать в качестве аргумента для add ().

const char some[] = "some";

Далее вам нужно исправить синтаксис в параметрах шаблона вашего правила:

rule<std::string::iterator, double()>

Обратите внимание на скобки, чтобы сделать double объявлением функтора, а не ванильным двойником, для ленивых вычислений.

Далее вам нужно использовать синтаксис выше для вашего семантического действия.

[ boost::phoenix::bind(floatDecs.add, boost::phoenix::val(some), _1) ];

Честно говоря, я не уверен, почему это работает, потому что я не эксперт по фениксу, но ссылка в комментариях ‘sehe’ выше дала ответ. Кроме того, вы лаяли не то дерево с crefнет никаких указаний от add()заявление о том, что требуется ссылка. val это то, что вам нужно, чтобы включить some Переменная в Феникса-счастливого ленивого аргумента.

Наконец, вам просто нужно предоставить некоторые разумные данные испытаний.

Код выше должен работать для вас сейчас.

3

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

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