你好,我正在尝试使用Spirit x3将字符串填充到向量中,但是出现以下错误。代码直接来自文档,除了向量使用字符串。
error: no matching function for call to
std::vector<std::__cxx11::basic_string<char>
>::push_back(boost::spirit::x3::unused_type&)’
auto push_back = [&](auto& ctx){ slt.push_back(_attr(ctx)); };`
我的代码看起来像这样,我认为所有必需的包含物都在上面(它在类方法中):
#include <boost/spirit/home/x3.hpp>
#include <algorithm>
#include <bitset>
#include <fstream>
#include <iostream>
#include <iterator>
#include <map>
#include <sstream>
#include <stdexcept>
#include <string>
#include <vector>
namespace x3 = boost::spirit::x3;
namespace ascii = boost::spirit::x3::ascii;
using x3::double_;
using x3::phrase_parse;
using x3::_attr;
using x3::parse;
using x3::lit;
using x3::char_;
using x3::lexeme;
using x3::alpha;
using x3::alnum;
using x3::skip;
using ascii::space;
/*Something,something.......*/
auto name = x3::rule<class name>{}
= char_("a-zA-Z") >> *char_("a-z_A-Z0-9");
auto args_l = x3::rule<class l>{}
= " " >> (name % skip(space)[","]);
auto comment = x3::rule<class comment>{}
= "//" >> *char_;
auto iter_start = line.begin();
auto iter_end = line.end();
vector<string> slt;
auto push_back = [&](auto& ctx){ slt.push_back(_attr(ctx)); };
bool result = parse(
iter_start,
iter_end,
name[push_back] >> -args_l >> *(char_(" "))
);
/某事....... /
答案 0 :(得分:1)
您的规则定义不公开属性。
就像@llonesmiz指出的那样,请解决此问题:
auto name = x3::rule<class name, std::string>{}
= char_("a-zA-Z") >> *char_("a-z_A-Z0-9");
并查看 Live On Wandbox (boost-1.67)
注意:错误
如果您使用Boost 1.65-1.66,则会遇到 How to make a recursive rule in boost spirit x3 in VS2017, (Live On Wandbox 在Boost 1.67(以及更早的版本,例如Live on Wandbox/Boost 1.64)中已修复的问题
#include <boost/spirit/home/x3.hpp>
namespace x3 = boost::spirit::x3;
namespace P {
using namespace x3;
auto name = x3::rule<class name, std::string>{}
= char_("a-zA-Z") >> *char_("a-z_A-Z0-9");
auto args_l = x3::rule<class l>{}
= " " >> (name % skip(space)[","]);
auto comment = x3::rule<class comment>{}
= "//" >> *char_;
}
#include <iostream>
#include <iomanip>
int main() {
std::string const line = "a90_b";
auto iter_start = line.begin();
auto iter_end = line.end();
std::vector<std::string> slt;
auto push_back = [&](auto& ctx){ slt.push_back(x3::_attr(ctx)); };
bool result = parse(
iter_start,
iter_end,
P::name[push_back] >> -P::args_l >> *x3::char_(" ")
);
for (auto& tok: slt) {
std::cout << std::quoted(tok) << "\n";
}
if (iter_start!=iter_end)
std::cout << "Remaining unparsed: " << std::quoted(std::string(iter_start, iter_end)) << "\n";
return result? 0 : 255;
}
答案 1 :(得分:1)
在按anwering原样提出问题之后,我查看了您的代码。
考虑其余的代码,也许这就是您所追求的:
lexeme[]
来抑制船长(https://stackoverflow.com/questions/49768603/boost-spirit-classic-skip-parser-to-skip-empty-lines-are-end-of-csv)#include <boost/spirit/home/x3.hpp>
namespace x3 = boost::spirit::x3;
namespace P {
using namespace x3;
auto name = x3::rule<class name, std::string>{}
= lexeme [char_("a-zA-Z") >> *char_("a-z_A-Z0-9")];
auto comment = x3::rule<class comment>{}
= "//" >> *(char_-eol)
| "/*" >> *(char_ - "*/") >> "*/";
auto args_l = skip(space|comment) [name % ','];
}
#include <iostream>
#include <iomanip>
int main() {
for (std::string const line : {
"a90_b",
"a90_b, /*comment ignored*/ b8, //more stuff\nz",
})
{
std::cout << "Parsing " << std::quoted(line) << "\n";
auto iter_start = line.begin();
auto iter_end = line.end();
std::vector<std::string> slt;
bool result = parse(iter_start, iter_end, P::args_l, slt);
if (result) {
for (auto& tok: slt) {
std::cout << " -> " << std::quoted(tok) << "\n";
}
} else {
std::cout << "Parsed failed\n";
}
if (iter_start!=iter_end) {
std::cout << "Remaining unparsed: " << std::quoted(std::string(iter_start, iter_end)) << "\n";
}
}
}
打印
Parsing "a90_b"
-> "a90_b"
Parsing "a90_b, /*comment ignored*/ b8, //more stuff
z"
-> "a90_b"
-> "b8"
-> "z"