Проблема грамматики духовной кармы, когда одно правило использует BOOST_FUSION_ADAPT_STRUCT

Я пытаюсь создать грамматику Духовной Кармы, которая состоит из нескольких правил. Эта грамматика предназначена для создания строки формата «(0, 1, 2, 3), (4, 5, 6, 7), (8, 9, 10, 11)». Правило для распечатки каждой отдельной структуры, которую я вызываю RowData, использует BOOST_FUSION_ADAPT_STRUCT, чтобы распечатать все поля этой структуры. Если грамматика включает только это правило, грамматика работает нормально. Тем не менее, я использую эту структуру в качестве значения std :: map. Ключ в целое число, но я не забочусь об этом значении и хочу отбросить его. Я создал правила для разбора std :: map, но правило, которое обрабатывает std :: pair, не компилируется для BOOST_SPIRIT_ASSERT_MATCH. Я создал небольшой кусочек кода, который генерирует эту проблему. Линия pairRule = bs::karma::omit << rowDataRule; Если у кого-то есть идея, в чем проблема или как я могу сделать это по-другому, я был бы признателен за помощь.

Редактировать: я использую gcc 4.8.3 на OpenSUSE 13.2, но получаю ту же ошибку с gcc 4.8.2 на Ubuntu 14.04 LTS.

main.cpp

#include <iostream>
#include <map>

#include <boost/cstdint.hpp>
#include <boost/fusion/adapted/struct/adapt_struct.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/fusion/include/make_tuple.hpp>
#include <boost/fusion/include/std_pair.hpp>
#include <boost/spirit/include/karma.hpp>

namespace bs = boost::spirit;

struct RowData
{
RowData() :
field0(0),
field1(0),
field2(0),
field3(0)
{
}

boost::uint64_t field0;
boost::uint64_t field1;
boost::uint64_t field2;
boost::uint64_t field3;
};

BOOST_FUSION_ADAPT_STRUCT(
RowData,
(boost::uint64_t, field0)
(boost::uint64_t, field1)
(boost::uint64_t, field2)
(boost::uint64_t, field3)
)

template <typename OutputIterator>
struct RowDataGrammar :
bs::karma::grammar< OutputIterator, std::map<boost::uint64_t, RowData>() >
{
RowDataGrammar() : RowDataGrammar::base_type(allRowsRule)
{
rowDataRule =
bs::karma::lit("(") <<
bs::karma::ulong_ <<
bs::karma::lit(", ") <<
bs::karma::ulong_ <<
bs::karma::lit(", ") <<
bs::karma::ulong_ <<
bs::karma::lit(", ") <<
bs::karma::ulong_ <<
bs::karma::lit(")");

// I only want the value from the map. The key is dropped.
pairRule = bs::karma::omit << rowDataRule;

allRowsRule = pairRule % ", ";
}

private:
bs::karma::rule< OutputIterator, RowData() > rowDataRule;
bs::karma::rule< OutputIterator, std::pair<boost::uint64_t, RowData>() > pairRule;
bs::karma::rule< OutputIterator, std::map<boost::uint64_t, RowData>() >  allRowsRule;
};

int main(int argc, char** argv)
{
std::map<boost::uint64_t, RowData> rowMap;

RowData rowData;
rowData.field0 = 0;
rowData.field1 = 1;
rowData.field2 = 2;
rowData.field3 = 3;
rowMap.insert(std::make_pair(10, rowData));

rowData.field0 = 6;
rowData.field1 = 7;
rowData.field2 = 8;
rowData.field3 = 9;
rowMap.insert(std::make_pair(20, rowData));

std::string generatedString;
std::back_insert_iterator<std::string> sink(generatedString);
RowDataGrammar< std::back_insert_iterator<std::string> > grammar;

bs::karma::generate(sink, grammar, rowMap);

std::cout << "output :" << generatedString << std::endl;
}

Сообщение об ошибке:

In file included from /usr/include/boost/fusion/support/tag_of.hpp:16:0,
from /usr/include/boost/fusion/support/category_of.hpp:11,
from /usr/include/boost/fusion/adapted/struct/detail/extension.hpp:13,
from /usr/include/boost/fusion/adapted/struct/adapt_struct.hpp:19,
from karmaTest.cpp:5:
/usr/include/boost/spirit/home/karma/nonterminal/rule.hpp: In instantiation of ‘static void boost::spirit::karma::rule<OutputIterator, T1, T2, T3, T4>::define(boost::spirit::karma::rule<OutputIterator, T1, T2, T3, T4>&, const Expr&, mpl_::false_) [with Auto = mpl_::bool_<false>; Expr = boost::proto::exprns_::expr<boost::proto::tagns_::tag::shift_left, boost::proto::argsns_::list2<const boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::spirit::tag::omit>, 0l>&, boost::spirit::karma::rule<std::back_insert_iterator<std::basic_string<char> >, RowData(), boost::spirit::unused_type, boost::spirit::unused_type, boost::spirit::unused_type>&>, 2l>; OutputIterator = std::back_insert_iterator<std::basic_string<char> >; T1 = std::pair<long unsigned int, RowData>(); T2 = boost::spirit::unused_type; T3 = boost::spirit::unused_type; T4 = boost::spirit::unused_type; mpl_::false_ = mpl_::bool_<false>]’:
/usr/include/boost/spirit/home/karma/nonterminal/rule.hpp:229:19:   required from ‘boost::spirit::karma::rule<OutputIterator, T1, T2, T3, T4>& boost::spirit::karma::rule<OutputIterator, T1, T2, T3, T4>::operator=(const Expr&) [with Expr = boost::proto::exprns_::expr<boost::proto::tagns_::tag::shift_left, boost::proto::argsns_::list2<const boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::spirit::tag::omit>, 0l>&, boost::spirit::karma::rule<std::back_insert_iterator<std::basic_string<char> >, RowData(), boost::spirit::unused_type, boost::spirit::unused_type, boost::spirit::unused_type>&>, 2l>; OutputIterator = std::back_insert_iterator<std::basic_string<char> >; T1 = std::pair<long unsigned int, RowData>(); T2 = boost::spirit::unused_type; T3 = boost::spirit::unused_type; T4 = boost::spirit::unused_type]’
karmaTest.cpp:54:18:   required from ‘RowDataGrammar<OutputIterator>::RowDataGrammar() [with OutputIterator = std::back_insert_iterator<std::basic_string<char> >]’
karmaTest.cpp:84:62:   required from here
/usr/include/boost/spirit/home/karma/nonterminal/rule.hpp:185:13: error: no matching function for call to ‘assertion_failed(mpl_::failed************ (boost::spirit::karma::rule<OutputIterator, T1, T2, T3, T4>::define(boost::spirit::karma::rule<OutputIterator, T1, T2, T3, T4>&, const Expr&, mpl_::false_) [with Auto = mpl_::bool_<false>; Expr = boost::proto::exprns_::expr<boost::proto::tagns_::tag::shift_left, boost::proto::argsns_::list2<const boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::spirit::tag::omit>, 0l>&, boost::spirit::karma::rule<std::back_insert_iterator<std::basic_string<char> >, RowData(), boost::spirit::unused_type, boost::spirit::unused_type, boost::spirit::unused_type>&>, 2l>; OutputIterator = std::back_insert_iterator<std::basic_string<char> >; T1 = std::pair<long unsigned int, RowData>(); T2 = boost::spirit::unused_type; T3 = boost::spirit::unused_type; T4 = boost::spirit::unused_type; mpl_::false_ = mpl_::bool_<false>]::error_invalid_expression::************)(boost::proto::exprns_::expr<boost::proto::tagns_::tag::shift_left, boost::proto::argsns_::list2<const boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::spirit::tag::omit>, 0l>&, boost::spirit::karma::rule<std::back_insert_iterator<std::basic_string<char> >, RowData(), boost::spirit::unused_type, boost::spirit::unused_type, boost::spirit::unused_type>&>, 2l>))’
BOOST_SPIRIT_ASSERT_MATCH(karma::domain, Expr);
^
/usr/include/boost/spirit/home/karma/nonterminal/rule.hpp:185:13: note: candidate is:
/usr/include/boost/mpl/assert.hpp:82:5: note: template<bool C> int mpl_::assertion_failed(typename mpl_::assert<C>::type)
int assertion_failed( typename assert<C>::type );
^
/usr/include/boost/mpl/assert.hpp:82:5: note:   template argument deduction/substitution failed:
/usr/include/boost/spirit/home/karma/nonterminal/rule.hpp:185:13: note:   cannot convert ‘boost::spirit::karma::rule<OutputIterator, T1, T2, T3, T4>::define(boost::spirit::karma::rule<OutputIterator, T1, T2, T3, T4>&, const Expr&, mpl_::false_)::error_invalid_expression185::assert_arg<mpl_::bool_<false>, boost::proto::exprns_::expr<boost::proto::tagns_::tag::shift_left, boost::proto::argsns_::list2<const boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::spirit::tag::omit>, 0l>&, boost::spirit::karma::rule<std::back_insert_iterator<std::basic_string<char> >, RowData(), boost::spirit::unused_type, boost::spirit::unused_type, boost::spirit::unused_type>&>, 2l> >()’ (type ‘mpl_::failed************ (boost::spirit::karma::rule<OutputIterator, T1, T2, T3, T4>::define(boost::spirit::karma::rule<OutputIterator, T1, T2, T3, T4>&, const Expr&, mpl_::false_) [with Auto = mpl_::bool_<false>; Expr = boost::proto::exprns_::expr<boost::proto::tagns_::tag::shift_left, boost::proto::argsns_::list2<const boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::spirit::tag::omit>, 0l>&, boost::spirit::karma::rule<std::back_insert_iterator<std::basic_string<char> >, RowData(), boost::spirit::unused_type, boost::spirit::unused_type, boost::spirit::unused_type>&>, 2l>; OutputIterator = std::back_insert_iterator<std::basic_string<char> >; T1 = std::pair<long unsigned int, RowData>(); T2 = boost::spirit::unused_type; T3 = boost::spirit::unused_type; T4 = boost::spirit::unused_type; mpl_::false_ = mpl_::bool_<false>]::error_invalid_expression::************)(boost::proto::exprns_::expr<boost::proto::tagns_::tag::shift_left, boost::proto::argsns_::list2<const boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::spirit::tag::omit>, 0l>&, boost::spirit::karma::rule<std::back_insert_iterator<std::basic_string<char> >, RowData(), boost::spirit::unused_type, boost::spirit::unused_type, boost::spirit::unused_type>&>, 2l>)’) to type ‘mpl_::assert<false>::type {aka mpl_::assert<false>}’
BOOST_SPIRIT_ASSERT_MATCH(karma::domain, Expr);

1

Решение

Как cv_and_he сказал, что я использовал опустить неправильно. Старый сотрудник, к которому я обратился, сказал мне то же самое. Исправленный код ниже.

main.cpp

#include <iostream>
#include <map>

#include <boost/cstdint.hpp>
#include <boost/fusion/adapted/struct/adapt_struct.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/fusion/include/make_tuple.hpp>
#include <boost/fusion/include/std_pair.hpp>
#include <boost/spirit/include/karma.hpp>

namespace bs = boost::spirit;

struct RowData
{
RowData() :
field0(0),
field1(0),
field2(0),
field3(0)
{
}

boost::uint64_t field0;
boost::uint64_t field1;
boost::uint64_t field2;
boost::uint64_t field3;
};

BOOST_FUSION_ADAPT_STRUCT(
RowData,
(boost::uint64_t, field0)
(boost::uint64_t, field1)
(boost::uint64_t, field2)
(boost::uint64_t, field3)
)

template <typename OutputIterator>
struct RowDataGrammar :
bs::karma::grammar< OutputIterator, std::map<boost::uint64_t, RowData>() >
{
RowDataGrammar() : RowDataGrammar::base_type(allRowsRule)
{
rowDataRule =
bs::karma::lit("(") <<
bs::karma::ulong_ <<
bs::karma::lit(", ") <<
bs::karma::ulong_ <<
bs::karma::lit(", ") <<
bs::karma::ulong_ <<
bs::karma::lit(", ") <<
bs::karma::ulong_ <<
bs::karma::lit(")");

// I only want the value from the map. The key is dropped.
pairRule = bs::karma::omit[bs::karma::ulong_] << rowDataRule;

allRowsRule = pairRule % ", ";
}

private:
bs::karma::rule< OutputIterator, RowData() > rowDataRule;
bs::karma::rule< OutputIterator, std::pair<boost::uint64_t, RowData>() > pairRule;
bs::karma::rule< OutputIterator, std::map<boost::uint64_t, RowData>() >  allRowsRule;
};

int main(int argc, char** argv)
{
std::map<boost::uint64_t, RowData> rowMap;

RowData rowData;
rowData.field0 = 0;
rowData.field1 = 1;
rowData.field2 = 2;
rowData.field3 = 3;
rowMap.insert(std::make_pair(10, rowData));

rowData.field0 = 6;
rowData.field1 = 7;
rowData.field2 = 8;
rowData.field3 = 9;
rowMap.insert(std::make_pair(20, rowData));

std::string generatedString;
std::back_insert_iterator<std::string> sink(generatedString);
RowDataGrammar< std::back_insert_iterator<std::string> > grammar;

bs::karma::generate(sink, grammar, rowMap);

std::cout << "output :" << generatedString << std::endl;
}
1

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


По вопросам рекламы ammmcru@yandex.ru
Adblock
detector