Boost spirit x3 tuple construction и implicit unused_type

byteit101 спросил: 13 июня 2018 в 07:48 в: c++

Чтение документации, я думаю, что нижеследующее должно работать правильно, но вместо этого оно не скомпилируется, если я не передаю вывод в phrase_parse, и в этом случае он работает правильно, хотя я не могу получить нужные данные. Похоже, что nvp_def имеет типы (string, unused_type, uin32_t), которые (когда я прочитал документацию) создавали бы кортеж, как я ожидаю, но это, очевидно, не так. Что мне не хватает, чтобы получить данные синтаксического анализа?

#include <boost/spirit/home/x3.hpp>
#include <tuple>
namespace x3 = boost::spirit::x3;x3::rule<class idtype, std::string> const idrule = "idrule";
auto const idrule_def = x3::lexeme[+x3::char_("a-zA-Z0-9")];x3::rule<class nvp, std::tuple<std::string, uint32_t>> const nvp = "nvp";
auto const nvp_def = idrule >> x3::char_(':') >> x3::hex;BOOST_SPIRIT_DEFINE(idrule, nvp);int main(int argc, char *argv[])
{
    std::tuple<std::string, uint32_t> output;    const std::string total =  "foo4bar:deadbeef";
    std::string::const_iterator first = total.begin();
    std::string::const_iterator const last = total.end();    bool r = x3::phrase_parse(first, last, nvp, x3::space, output);
}

Скомпилировать ошибку (попытка присвоить uint32_t из шестнадцатеричного кода в кортеж):

/usr/include/boost/spirit/home/x3/support/traits/move_to.hpp:62: error: no match for ‘operator=’ (operand types are ‘std::tuple<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, unsigned int>’ and ‘std::remove_reference<unsigned int&>::type {aka unsigned int}’)
         dest = std::move(src);
         ~~~~~^~~~~~~~~~~~~~~~

1 ответ

Есть решение
ildjarn ответил: 13 июня 2018 в 08:14

Основная проблема заключается в отсутствии: <boost/fusion/include/std_tuple.hpp>; без этого адаптера std::tuple не является допустимой последовательностью Fusion, поэтому Spirit, следовательно, не может использовать его для хранения составных атрибутов. (В вашем примере также отсутствует код <string> и <stdint.h>.)

Вторая проблема заключается в том, что x3::char_ имеет атрибут, но вы не 't требуется атрибут для разделительного двоеточия, поэтому nvp_def должен быть idrule >> ':' >> x3::hex или idrule >> x3::lit(':') >> x3::hex. Также обратите внимание, что фактическим атрибутом x3::hex является unsigned, поэтому использование поля uint32_t для его хранения может быть усечено на некоторых платформах.

sehe ответил: 13 июня 2018 в 08:34
С различными упрощениями coliru.stacked-crooked.com/a/cb4962d72929119d

Дополнительное видео по вопросу: Boost spirit x3 tuple construction и implicit unused_type

Tuples as Map Keys [C++/Boost]

C++: Print elements of a tuple