【发布时间】:2015-05-27 05:16:07
【问题描述】:
我正在尝试使用 Spirit.Qi 创建一个 GPIB 解析器。有时响应可以
要么是错误,要么是正常响应。这似乎是一个很好的用例
产生boost::variant的替代解析器;但是,如果其中之一
变体类型包含代码无法编译的字符串。这是一个简化的
重现错误的版本。
struct C1 {
std::string h{""};
int i{0};
};
BOOST_FUSION_ADAPT_STRUCT(C1, (std::string, h)(int, i))
struct C2 {
std::string h{""};
std::string c{};
};
BOOST_FUSION_ADAPT_STRUCT(C2, (std::string, h)(std::string, c))
using VariantType = boost::variant<C1, C2>;
int main() {
std::string s2{"C2:Zoo3"};
VariantType v1;
if(qi::parse(s1.begin(), s1.end(),
(qi::string("C1") >> ":" >> qi::int_) |
(qi::string("C2") >> ":" >> *qi::char_),
v1)) {
if(boost::get<C1>(&v1)) {
auto a1 = boost::get<C1>(v1);
std::cout << "Parsing Succeeded, a1 = " << a1.h << ":"
<< a1.i << std::endl;
}
else {
auto a2 = boost::get<C2>(v1);
std::cout << "Parsing Succeeded, a2 = " << a2.h << ":"
<< a2.c << std::endl;
}
}
else {
std::cout << "Parsing Failed" << std::endl;
}
return 0;
}
除了*qi::char_(例如qi::string)之外,我已经尝试过各种解析器,但均无济于事。如果我将 C2::c 更改为 char 它适用于 1 个字符。到目前为止,我发现的最佳解决方法是将C2::c 更改为std::vector<char>,这可以正常工作但并不理想。我还尝试告诉 Qi std::string 是一个类似于 here 的容器。但是qi知道std::string是什么,所以我很确定它忽略了我的自定义。我认为这完全是因为 std::string 不是 POD 并且在规则放松之前不受联合的支持,但是当它不在结构中时它可以与 boost::variant 一起使用,并且 std::vector 可以使用。任何想法/解决方法将不胜感激。
*注意:我没有发布编译器错误,因为它们很长且被破坏,我认为这是std::string 和变体的已知问题。如果他们有帮助,请告诉我,我会发布。
【问题讨论】:
-
Qi 知道什么是字符串,所以自定义是多余的:coliru.stacked-crooked.com/a/508941b22ad5bc1d。 POD-ness 当然不是必需的(Boost Variant 的目的是什么?)。 (不要打电话给
variants 工会,这会造成不必要的混乱。)
标签: c++ boost boost-spirit-qi