Поддерживать BOOST_FUSION_ADAPT_STRUCT для объектов с фиксированными массивами?

Предположим, у меня уже есть структура, которая выглядит так:

struct LETTER
{
    double one;
    char[12] two;
    double three;
    char[12] four;
};

И мои входы разделены запятыми, например:

"32,CATSANDDOGS,42,WHAT"
"43,BATANDZEBRAS,23,PARROT"

Я пытался адаптировать этот пример (Spirit Qi: правило для char [5]), чтобы прокрутить BOOST_FUSION_ADAPT_STRUCT, но безуспешно. Я попытался использовать std::array, как показано здесь (http://www.boost.org/doc/libs/1_64_0/libs/spirit/example/qi/boost_array.cpp), но мне не удалось заставить его работать в структуре. Возможно ли то, что я пытаюсь сделать? Что я здесь делаю неправильно? Я бы подумал, что это будет самый очевидный вариант использования.

Возможно ли то, что я пытаюсь сделать?


person Carbon    schedule 27.11.2017    source источник
comment
Наиболее очевидный вариант использования использует массивы символов фиксированного размера? Это наиболее очевидно в C 1970-х годов. Просто используйте std::string, если вам нужны очевидные варианты использования.   -  person sehe    schedule 28.11.2017


Ответы (1)


Я предполагаю, что вы хотите написать идиоматический код C++ (который, очевидно, является целевым доменом для Spirit Qi), поэтому вы можете использовать std::string:

Прямой эфир на Coliru

#include <boost/fusion/adapted.hpp>
#include <boost/fusion/include/io.hpp>
#include <boost/spirit/include/qi.hpp>
#include <iostream>

namespace qi = boost::spirit::qi;

struct Letter {
    double one;
    std::string two;
    double three;
    std::string four;
};

BOOST_FUSION_ADAPT_STRUCT(Letter, one, two, three, four)

template <typename Iterator> struct LETTERParser : qi::grammar<Iterator, Letter()> {
    LETTERParser() : LETTERParser::base_type(start) {
        using namespace qi;

        _11c = repeat(11) [char_];
        start = skip(space) [ "LETTER" >> double_ >> _11c >> double_ >> _11c ];
    }
  private:
    qi::rule<Iterator, Letter()> start;
    qi::rule<Iterator, std::string()> _11c;
};

int main() {
    const std::string input("LETTER 42 12345678901 +Inf abcdefghijk  ");
    using It = std::string::const_iterator;

    LETTERParser<It> parser;
    Letter example;

    It f = input.begin(), l = input.end();

    if (phrase_parse(f, l, parser, qi::ascii::space, example)) {
        std::cout << "parsed: " << boost::fusion::as_vector(example) << "\n";
        std::cout << " example.one: " << example.one << "\n";
        std::cout << " example.two: '" << example.two << "'\n";
        std::cout << " example.three: " << example.three << "\n";
        std::cout << " example.four: '" << example.four << "'\n";
    } else {
        std::cout << "couldn't parse '" << input << "'\n";
    }

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

Отпечатки

parsed: (42 12345678901 inf abcdefghijk)
 example.one: 42
 example.two: '12345678901'
 example.three: inf
 example.four: 'abcdefghijk'
person sehe    schedule 28.11.2017
comment
ОК, круто, думаю, я попрошу команду примириться с std::string для этой структуры данных. - person Carbon; 28.11.2017