6

std::arrayboost::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;
}

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);

代わりは。これは機能しますが (-std=c++14 で clang 3.6.0 を使用)、このソリューションは非常に洗練されておらず、読みにくいと思います。

BOOST_FUSION_ADAPT_ADTだから私は std::array を次のように使用して融合シーケンスとして適応させようとしました:

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))

次に Vertex を特殊化x3::traits::is_containerして x3 に std::array をコンテナーとして扱わないように指示します。

namespace boost { namespace spirit { namespace x3 { namespace traits {
  template<> struct is_container<Vertex> : public mpl::false_ {};
}}}}

ただし、これは x3 と組み合わせてコンパイルすることはできません。これはバグですか、それとも使い方が間違っていますか? たとえば、すべての x3 コードなしで呼び出すfusion::front(v)と、コンパイルして機能するので、コードが完全に間違っているわけではないと思います。

ただし、この単純な問題に対するフュージョン アダプターやセマンティック アクションを含まない x3 を使用した、よりクリーンなソリューションがあると確信しています。

4

1 に答える 1

0

あなたが投稿したコードは、ずさんなエラーでいっぱいです。そこに何かがコンパイルされることを期待する理由はありません。

とにかく、私はそれを片付けました¹。もちろん入れるべきだった

#include <boost/fusion/adapted/array.hpp>

残念ながら、それは単に機能しません。私は(あなたが言及したのと同じことを試した後、それについて読む前に:))とほぼ同じ結論に達しました。

これは、まだ実験段階にある Spirit X3 のユーザビリティの問題です。[spirit-general] メーリング リストで報告できます。通常、応答はかなり迅速です。


¹ 私がhttp://paste.ubuntu.com/12764268/で作業したものを見たい場合に備えて; x3::repeat(3)[x3::double_]比較用にも使っています。

于 2015-10-12T16:13:47.250 に答える