Boost Spirit Karma несколько опций

Я вижу ошибку, для которой я не вижу разрешение. Во-первых, соответствующий код:

namespace C {

struct RangeEntry {
size_t byte;
boost::optional<size_t> bit;
};

struct Range {
RangeEntry firstPart;
boost::optional<RangeEntry> secondPart;
boost::optional<size_t> shift;
};
}

BOOST_FUSION_ADAPT_STRUCT(
C::RangeEntry,
(size_t, byte)
(boost::optional<size_t>, bit)
)

BOOST_FUSION_ADAPT_STRUCT(
C::Range,
(C::RangeEntry , firstPart)
(boost::optional<C::RangeEntry> , secondPart)
(boost::optional<size_t> , shift)
)

... Declare the rules ...

karma::rule<Iterator, C::Range()> range;
karma::rule<Iterator, C::RangeEntry()> range_part;

... Define rules ...

range_part %= no_delimit[ulong_ << -(lit(":") << ulong_)];
range %= no_delimit[range_part << -(lit("-") << range_part)] << -(lit("<<") << ulong_);

На range %= часть, я получаю ошибку компиляции

/usr/include/boost/spirit/home/karma/numeric/detail/numeric_utils.hpp:504:30: error:
invalid operands to binary expression
('C::RangeEntry' and 'C::RangeEntry')
return floor(num / spirit::traits::pow10<T>(exp));
~~~ ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Я предполагаю, что он пытается сопоставить RangeEntry с правилом ulong_, но я не могу понять, почему? Что мне не хватает?

2

Решение

no_delimit Директива перегруппирует ваши открытые последовательности слияния. Обратите внимание, что следующее компилируется:

    range %= range_part << -(lit("-") << range_part) << -(lit("<<") << ulong_);

или даже

    range %= no_delimit[range_part << -(lit("-") << range_part) << -(lit("<<") << ulong_)];

AFAICT правила определены без разделителя, поэтому no_delimit здесь должен быть в любом случае избыточным.


Я «фантазировал» тип RangeEntry, чтобы сделать его самодостаточным образцом:

#include <boost/fusion/adapted.hpp>
#include <boost/spirit/include/karma.hpp>

namespace karma = boost::spirit::karma;

namespace C {
typedef std::pair<unsigned long, boost::optional<unsigned long> > RangeEntry;

struct Range {
RangeEntry firstPart;
boost::optional<RangeEntry> secondPart;
boost::optional<size_t> shift;
};
}

BOOST_FUSION_ADAPT_STRUCT(
C::Range,
(C::RangeEntry , firstPart)
(boost::optional<C::RangeEntry> , secondPart)
(boost::optional<size_t> , shift)
);

//... Declare the rules ...

int main()
{
typedef char* Iterator;
karma::rule<Iterator, C::Range()> range;
karma::rule<Iterator, C::RangeEntry()> range_part;

//... Define rules ...

using namespace karma;
range_part %= no_delimit[ulong_ << -(lit(":") << ulong_)];
range %= no_delimit[range_part << -(lit("-") << range_part) << -(lit("<<") << ulong_)];
}
5

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

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