Я использую boost :: spirit для разбора текста в структуру, содержащую массив фиксированного размера. Следуя примеру вboost :: spirit parsing в struct с std :: array
и пытается использовать его для разбора в структуры, содержащей зЬй :: массив (или повышающий :: массив) я признал, что из-за того, как BOOST_FUSION_ADAPT_STRUCT работ у меня есть для размещения помощника result_of :: adapt_array < some_array_type> :: type в структуре.
Я думаю, что должно быть возможно создать обертку, используя BOOST_FUSION_ADAPT_ADT, но, похоже, излишне просто избавиться от небольших накладных расходов адаптера в структуре. Поскольку у меня не так много примеров, я могу жить с ним с точки зрения памяти, но он также вводит некоторый шум.
Я также думаю, что можно создать адаптер, который получается из типа массива, а не инкапсулировать его, чтобы скрыть некоторые из шумов, но это заставит меня изменить все существующие структуры, и это приведет к утечке парсера накладных расходов наружу что не является хорошим решением.
Есть ли что-то очевидное Я приближаюсь к неправильному или существуют новые помощники, которые направляют накладные расходы в фоновом режиме, чтобы их можно было инкапсулировать в парсер?
Я знаю Using std::array as Attribute for boost::spirit::x3.
Вот мой текущий код:
#include <string>
#include <array>
#include <boost/spirit/include/qi.hpp>
namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;
// ...code from http://www.boost.org/doc/libs/1_60_0/libs/spirit/example/qi/boost_array.cpp here
typedef result_of::adapt_array<std::array<double, 6> >::type AdaptedArrayType;
struct StructWithArray
{
StructWithArray()
: adaptedAry_(ary_)
{}
double dummy_; // see https://stackoverflow.com/questions/19823413/spirit-qi-attribute-propagation-issue-with-single-member-struct
std::array<double, 6> ary_;
AdaptedArrayType adaptedAry_;
};
BOOST_FUSION_ADAPT_STRUCT(
StructWithArray
,
(double, dummy_)
(AdaptedArrayType, adaptedAry_)
)
template <typename Iterator, typename Skipper>
struct StructWithArrayParser
: qi::grammar<Iterator, StructWithArray(), Skipper>
{
StructWithArrayParser() : StructWithArrayParser::base_type(start)
{
using qi::double_;
arrayLine %= double_ > double_ > double_ > double_ > double_ > double_;
start %= double_ > arrayLine;
}
qi::rule<Iterator, AdaptedArrayType(), Skipper> arrayLine;
qi::rule<Iterator, StructWithArray(), Skipper> start;
};
int main() {
std::string arrayStr = "0 1 2 3 4 5 6";
std::string::const_iterator it = arrayStr.begin();
std::string::const_iterator endIt = arrayStr.end();
StructWithArrayParser<std::string::const_iterator, ascii::space_type> grammar;
StructWithArray structWithArray;
bool ret = phrase_parse(it, endIt, grammar, ascii::space, structWithArray);
return 0;
}
После проверки всех перестановок '{г ++, звоном ++} -std = {C++ 03, C++ 11, гр ++ 14} 'с boost 1.58,59,60 Я выяснил, что неверно понял вопрос. В ближайшее время – sehe
Обновлен ответ с наилучшим обходным решением, которое я мог (легко) достичь. Мне кажется, вы могли бы с этим справиться, чтобы имитировать то же самое с 'std :: array', но он не готов – sehe
Фантастический обходной способ :) Именно то, на что я надеялся. Я могу с радостью жить с boost :: array, но сделаю редактирование, если у меня найдется время, чтобы заставить его работать с std :: array. Также замечательно, что ваше решение указало мне на BOOST_PP_VARIADICS; так проще. –