ith*_*ron 6 c++ boost-spirit stdarray c++14 boost-spirit-x3
我正在尝试std::array使用boost :: spirit的最新版本x3(包含在boost 1.54中)将数字列表解析为固定大小的容器.由于std::array具有必要的功能,因此它被检测为容器,但缺少插入功能,使其不兼容.这是我想要完成的一个简短示例:
#include <boost/spirit/home/x3.hpp>
#include <array>
#include <iostream>
#include <string>
namespace x3 = boost::spirit::x3;
namespace ascii = boost::spirit::x3::ascii;
typedef std::array<double, 3> Vertex;
int main(int, char**) {
using x3::double_;
using ascii::blank;
std::string input = "3.1415 42 23.5";
auto iter = input.begin();
auto vertex = x3::rule<class vertex, Vertex>{} =
double_ >> double_ >> double_;
Vertex v;
bool const res = x3::phrase_parse(iter, input.end(), vertex, blank, v);
if (!res || iter != input.end()) return EXIT_FAILURE;
std::cout << "Match:" << std::endl;
for (auto vi : v) std::cout << vi << std::endl;
return EXIT_SUCCESS;
}
Run Code Online (Sandbox Code Playgroud)
由于std::array没有insert功能,因此无法编译.作为一种解决方法,我使用了语义操作:
auto vertex() {
using namespace x3;
return rule<class vertex_id, Vertex>{} =
double_[([](auto &c) { _val(c)[0] = _attr(c); })] >>
double_[([](auto &c) { _val(c)[1] = _attr(c); })] >>
double_[([](auto &c) { _val(c)[2] = _attr(c); })];
}
Run Code Online (Sandbox Code Playgroud)
然后打电话
x3::phrase_parse(iter, input.end(), vertex(), blank, v);
Run Code Online (Sandbox Code Playgroud)
代替.这是有效的(使用clang 3.6.0和-std = c ++ 14),但我认为这个解决方案非常不优雅且难以阅读.
所以我尝试将std :: array作为融合序列使用,BOOST_FUSION_ADAPT_ADT如下所示:
BOOST_FUSION_ADAPT_ADT(
Vertex,
(double, double, obj[0], obj[0] = val)
(double, double, obj[1], obj[1] = val)
(double, double, obj[2], obj[2] = val))
Run Code Online (Sandbox Code Playgroud)
然后专门x3::traits::is_container为Vertex告诉x3不要将std :: array视为容器:
namespace boost { namespace spirit { namespace x3 { namespace traits {
template<> struct is_container<Vertex> : public mpl::false_ {};
}}}}
Run Code Online (Sandbox Code Playgroud)
但这不会与x3一起编译.这是一个错误还是我使用它错了?调用例如fusion::front(v)没有所有x3代码编译和工作,所以我想我的代码并不完全错误.
但是我确信有一个更简洁的解决方案,x3不涉及任何融合适配器或语义操作来解决这个简单的问题.
您发布的代码充满了草率的错误。确实,没有理由期望其中的任何内容都能编译。
\n\n无论如何,我清理了\xc2\xb9。当然你应该包括
\n\n#include <boost/fusion/adapted/array.hpp>\nRun Code Online (Sandbox Code Playgroud)\n\n遗憾的是它根本不起作用。我得出的结论与(在尝试了您提到的相同事情之后,在阅读它之前:))大致相同。
\n\n这是 Spirit X3 的可用性问题 - 该产品仍处于实验阶段。您可以在 [spirit-general] 邮件列表中报告它。响应通常非常快。
\n\n\xc2\xb9 如果你想看看我使用的内容http://paste.ubuntu.com/12764268/;我也用过,x3::repeat(3)[x3::double_]对比一下。