2

これは何時間も私を悩ませてきましたが、それを機能させる方法がわかりません。ルールが使用されるたびに何かをしたいだけです。この例では、カウンターをインクリメントします。ルールを明示的に指定せず、boost::spirit::karma::generate の呼び出しで使用すると、機能します。しかし、すべてをルールに入れようとすると、コンパイルされず、長いエラー メッセージから何の洞察も得られません。

#include <iostream>
#include <string>

#include <boost/spirit/include/karma.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>

int main()
{
    using boost::spirit::karma::eps;
    using boost::spirit::karma::int_;
    using boost::spirit::karma::lit;
    using boost::spirit::karma::eol;
    using boost::phoenix::val;
    using boost::phoenix::ref;
    using boost::spirit::karma::generate;
    using boost::spirit::karma::rule;

    typedef std::back_insert_iterator<std::string> OutputIteratorType;

    std::string s;
    std::back_insert_iterator<std::string> sink(s);
    int lineNum = 0;

    generate(sink, eps[ref(lineNum) += 10] << lit("Line number ") << lit(lineNum) << lit(": ") << int_ << eol, 123);
    generate(sink, eps[ref(lineNum) += 10] << lit("Line number ") << lit(lineNum) << lit(": ") << int_ << eol, 123);

    // Will not compile
    //rule<OutputIteratorType, int()> testRule = eps[ref(lineNum) += 10] << lit("Line number ") << lit(lineNum) << lit(": ") << int_ << eol;
    //generate(sink, testRule, 123);
    //generate(sink, testRule, 123);

    std::cout << s;
    return 0;
}

(上で最もエレガントなboost::spiritバージョンを見ることができますが、ラムダ関数またはメンバー関数を使用するとすべて同じ結果になります。「ダイレクトメソッド」は機能しますが、「ルールメソッド」は機能しません。)

残念ながら、これをカバーするドキュメント、例、またはその他のリソースも見つかりません。参考文献にも非常に感謝しています。

4

1 に答える 1

3

これは boost::phoenix V2 の問題です (どれかは聞かないでください ;-)) したがって、V3 を使用するとうまくいきます。

さらに、属性を int ジェネレーターに与え、印刷時に lineNum を参照する必要があります。

#include <iostream>
#include <string>

#define BOOST_SPIRIT_USE_PHOENIX_V3

#include <boost/spirit/include/karma.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>

int main() {
  using boost::spirit::karma::eps;
  using boost::spirit::karma::int_;
  using boost::spirit::karma::lit;
  using boost::spirit::karma::eol;
  using boost::spirit::karma::_1;
  using boost::spirit::karma::_val;
  using boost::phoenix::val;
  using boost::phoenix::ref;
  using boost::spirit::karma::generate;
  using boost::spirit::karma::rule;

  typedef std::back_insert_iterator<std::string> OutputIteratorType;

  std::string s;
  std::back_insert_iterator<std::string> sink(s);
  int lineNum = 0;

  rule<OutputIteratorType, int()> testRule = eps[ref(lineNum) += 10]
      << lit("Line number ") << lit(ref(lineNum)) << lit(": ")
      << int_[_1 = _val] << eol;
  generate(sink, testRule, 123);
  generate(sink, testRule, 123);

  std::cout << s;
  return 0;
}
于 2013-08-09T10:04:50.870 に答える