title: Boost Spirit X3 cannot compile repeat directive with variable factor
body: <p>I am trying to use the Boost Spirit X3 directive <strong>repeat</strong> with a repetition factor that is variable. The basic idea is that of a header + payload, where the header specifies the size of the payload. A simple example “3 1 2 3” is interpreted as header = 3, data= {1, 2, 3} (3 integers).</p>
  
  <p>I could only find examples from the spirit qi documentation. It uses boost phoenix reference to wrap the variable factor: <a href="http://www.boost.org/doc/libs/1_50_0/libs/spirit/doc/html/spirit/qi/reference/directive/repeat.html">http://www.boost.org/doc/libs/1_50_0/libs/spirit/doc/html/spirit/qi/reference/directive/repeat.html</a></p>
  
  <pre><code>std::string str;
  int n;
  test_parser_attr("\x0bHello World",
      char_[phx::ref(n) = _1] &gt;&gt; repeat(phx::ref(n))[char_], str);
  std::cout &lt;&lt; n &lt;&lt; ',' &lt;&lt; str &lt;&lt; std::endl;  // will print "11,Hello World"
  </code></pre>
  
  <p>I wrote the following simple example for spirit x3 without luck:</p>
  
  <pre><code>#include &lt;boost/spirit/home/x3.hpp&gt;
  #include &lt;boost/spirit/include/phoenix.hpp&gt;
  #include &lt;string&gt;
  #include &lt;iostream&gt;
  
  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 = [&amp;n]( auto &amp;ctx ) { n = x3::_attr(ctx); };
    bool r = phrase_parse( begin, end, uint_[f] &gt;&gt; repeat(boost::phoenix::ref(n))[int_], space );
    if ( r &amp;&amp; begin == end  )
      cout &lt;&lt; "Parse success!" &lt;&lt; endl; 
    else
      cout &lt;&lt; "Parse failed, remaining: " &lt;&lt; string(begin,end) &lt;&lt; endl;
  
    return 0;
  }
  </code></pre>
  
  <p>Compiling the code above with boost 1.59.0 and clang++ (flags: -std=c++14) gives the following:</p>
  
  <pre><code>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&lt;unsigned int&gt;')
  
              typename RepeatCountLimit::type i{};
  </code></pre>
  
  <p>If I hardcode <code>repeat(3)</code> instead of <code>repeat(boost::phoenix::ref(n))</code> it works properly, but it is not a possible solution since it should support a variable repetition factor. </p>
  
  <p>Compilation with <code>repeat(n)</code> completes successfully, but it fails parsing with the following output:
  <code>“Parse failed, remaining: 1 2 3"</code></p>
  
  <p>Looking at the source code for <code>boost/spirit/home/x3/directive/repeat.hpp:72</code> it calls the empty constructor for template type <code>RepeatCountLimit::type</code> variable <code>i</code> and then assign during the for loop, iterating over min and max. However since the type is a reference it should be initialized in the constructor, so compilation fails. Looking at the equivalent source code from the previous library version boost/spirit/home/qi/directive/repeat.hpp:162 it is assigned directly:</p>
  
  <pre><code>        typename LoopIter::type i = iter.start();
  </code></pre>
  
  <p>I am not sure what I am doing wrong here, or if x3 currently does not support variable repetition factors.  I would appreciate some help solving this issue. Thank you.</p>