ブースト スピリット X3 ディレクティブリピートを可変の繰り返し係数で使用しようとしています。基本的な考え方は、ヘッダーがペイロードのサイズを指定する、ヘッダー + ペイロードの考え方です。簡単な例「3 1 2 3」は、ヘッダー = 3、データ = {1, 2, 3} (3 つの整数) として解釈されます。
精神気のドキュメントからしか例を見つけることができませんでした。ブースト フェニックス リファレンスを使用して可変因子をラップします。
std::string str;
int n;
test_parser_attr("\x0bHello World",
char_[phx::ref(n) = _1] >> repeat(phx::ref(n))[char_], str);
std::cout << n << ',' << str << std::endl; // will print "11,Hello World"
運が悪い場合、精神 x3 の次の簡単な例を書きました。
#include <boost/spirit/home/x3.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <string>
#include <iostream>
namespace x3 = boost::spirit::x3;
using x3::uint_;
using x3::int_;
using x3::phrase_parse;
using x3::repeat;
using x3::space;
using std::string;
using std::cout;
using std::endl;
int main( int argc, char **argv )
{
string data("3 1 2 3");
string::iterator begin = data.begin();
string::iterator end = data.end();
unsigned int n = 0;
auto f = [&n]( auto &ctx ) { n = x3::_attr(ctx); };
bool r = phrase_parse( begin, end, uint_[f] >> repeat(boost::phoenix::ref(n))[int_], space );
if ( r && begin == end )
cout << "Parse success!" << endl;
else
cout << "Parse failed, remaining: " << string(begin,end) << endl;
return 0;
}
上記のコードをブースト 1.59.0 と clang++ (フラグ: -std=c++14) でコンパイルすると、次の結果が得られます。
boost_1_59_0/boost/spirit/home/x3/directive/repeat.hpp:72:47: error: no matching constructor for
initialization of 'proto_child0' (aka 'boost::reference_wrapper<unsigned int>')
typename RepeatCountLimit::type i{};
repeat(3)代わりにハードコードするrepeat(boost::phoenix::ref(n))と正しく動作しますが、可変繰り返し係数をサポートする必要があるため、可能な解決策ではありません。
コンパイルはrepeat(n)正常に完了しますが、解析に失敗し、次の出力が表示されます。
“Parse failed, remaining: 1 2 3"
ソースコードを見ると、boost/spirit/home/x3/directive/repeat.hpp:72テンプレート型RepeatCountLimit::type変数の空のコンストラクターが呼び出さiれ、for ループ中に割り当てられ、min と max が繰り返されます。ただし、型は参照であるため、コンストラクターで初期化する必要があるため、コンパイルは失敗します。以前のライブラリ バージョン boost/spirit/home/qi/directive/repeat.hpp:162 からの同等のソース コードを見ると、直接割り当てられています。
typename LoopIter::type i = iter.start();
ここで何が間違っているのか、または x3 が現在可変繰り返し係数をサポートしていないのかどうかはわかりません。この問題を解決するための助けをいただければ幸いです。ありがとうございました。