gpt4 book ai didi

c++ - 是否有 boost::phoenix::at_c 结合 boost::spirit::qi::grammar 的替代方案

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:25:46 25 4
gpt4 key购买 nike

我已经创建了一个测试应用程序来说明我的问题。它解析以“a=”或“b=”开头并以“\r\n”分隔的整数列表。该列表包含以任何顺序多次出现的这些字段。

#include <string>
#include <vector>
#include <iostream>

#include <boost/spirit/include/qi.hpp>

#include <boost/spirit/include/phoenix.hpp>

#include <boost/fusion/include/adapt_struct.hpp>


typedef std::vector<unsigned int> uint_vector_t;

std::ostream& operator<<(std::ostream& out, const uint_vector_t &data)
{
for (unsigned int i(0); i < data.size(); i++)
{
out << data[i] << '\n';
}
return out;
}

struct MyStruct
{
uint_vector_t m_aList;
uint_vector_t m_bList;
};

BOOST_FUSION_ADAPT_STRUCT
(
MyStruct,
(uint_vector_t, m_aList)
(uint_vector_t, m_bList)
)
;

template<typename Iterator>
struct MyParser : public boost::spirit::qi::grammar<Iterator,
MyStruct()>
{
MyParser() :
MyParser::base_type(Parser, "Parser")
{
using boost::spirit::qi::uint_;
using boost::spirit::qi::_val;
using boost::spirit::qi::_1;

using boost::phoenix::at_c;
using boost::phoenix::push_back;

Parser =
*(
aParser [push_back(at_c<0>(_val), _1)]
|
bParser [push_back(at_c<1>(_val), _1)]
);
aParser = "a=" >> uint_ >> "\r\n";
bParser = "b=" >> uint_ >> "\r\n";
}
boost::spirit::qi::rule<Iterator, MyStruct()> Parser;
boost::spirit::qi::rule<Iterator, unsigned int()> aParser, bParser;
};

int main()
{
using boost::spirit::qi::phrase_parse;

std::string input("a=0\r\nb=7531\r\na=2\r\na=3\r\nb=246\r\n");
std::string::const_iterator begin = input.begin();
std::string::const_iterator end = input.end();
MyParser<std::string::const_iterator> parser;

MyStruct result;
bool succes = phrase_parse(begin, end, parser, "", result);
assert(succes);

std::cout << "===A===\n" <<result.m_aList << "===B===\n" << result.m_bList << std::endl;
}

在实践中,需要解析的字段更多,类型不同。我对这种方法的反对在于以下表达: [push_back(at_c<0>(_val), _1)]这是分配和 MyStruct 的第一个元素之间的“隐藏依赖性”。这使得代码易受更改。如果更改了结构,它可能仍会编译,但不再执行预期的操作。

我希望这样的结构: [push_back(at_c<0>bind(&MyStruct::aList, arg1)(_val), _1)]参见 this.从而真正名正言顺。

这样的事情可能吗?还是我应该采取完全不同的方法?

最佳答案

Phoenix 也允许你绑定(bind)数据成员,所以你可以这样写:

Parser = 
*( aParser [push_back(bind(&MyStruct::m_aList, _val), _1)]
| bParser [push_back(bind(&MyStruct::m_bList, _val), _1)]
);

此外,在这种情况下,您的结构不再需要 FUSION_ADAPT 魔法。

关于c++ - 是否有 boost::phoenix::at_c 结合 boost::spirit::qi::grammar 的替代方案,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3290389/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com