boost :: spiritの最新リリースx3(boost 1.54に含まれています)を使用して固定サイズのstd::array
コンテナに数値のリストを解析しようとしています。 std::array
には必要な機能があるため、コンテナとして検出されますが、挿入機能がないため互換性がありません。ここ は、私が達成しようとしているものの短い例です:boost :: spirit :: x3の属性として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;
}
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); })];
}
と、代わりに
x3::phrase_parse(iter, input.end(), vertex(), blank, v);
を呼び出す:私はセマンティックアクションを使用回避策として 。これは(clang 3.6.0と-std = C++ 14を併用して)動作しますが、このソリューションは非常に面白くないし、読みにくいと思います。コンテナとしてのstd ::配列を処理しないようにX3を伝えるために頂点のためのx3::traits::is_container
を専門に、その後
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))
と::
は、だから私はBOOST_FUSION_ADAPT_ADT
そう等を用いて融合配列としてのstd ::配列を適応しようとした
namespace boost { namespace spirit { namespace x3 { namespace traits {
template<> struct is_container<Vertex> : public mpl::false_ {};
}}}}
しかし、これはx3と組み合わせてコンパイルされません。これはバグですか、私は間違って使っていますか? fusion::front(v)
すべてのx3コードがコンパイルされずに動作するので、私のコードは完全に間違っているとは思わない。
しかし、この単純な問題では、融合アダプタやセマンティックアクションを含まないx3のクリーナーソリューションがあると確信しています。
'boost :: array'はオプションですか?私は、 "boost/fusion/include/boost_array.hpp"、 "double_ >> double_ >> double_'などは動作するはずです。 – llonesmiz
私はそれらの愚かなエラーを修正しました。申し訳ありません。 'boost :: array'は、' std :: array'に大きく依存する既存のコードをインターフェースしているので、オプションではありません。 – ithron
あなたのアプローチをコンパイルするために[これはひどいハックです](http://coliru.stacked-crooked.com/a/412c97fecfa4e4b1)。あなたはおそらくより良い答え(または実際には良いもの)を待つべきです。 – llonesmiz