Search code examples
c++boostboost-spirit

Understanding parsing of constructor initializer for template


I'm trying to understand a program demonstrating boost/spirit.

In the following template definition:

template <typename Iterator>
struct roman : qi::grammar<Iterator,unsigned()> {
    roman() : roman::base_type(start)
    {
        using qi::eps;
        using qi::lit;
        using qi::_val;
        using qi::_1;
        using ascii::char_;

        start = eps[_val = 0] >>
            (
                +lit('M')[_val += 1000]
                ||  hundreds[_val += _1]
                ||  tens[_val += _1]
                ||  ones[_val += _1]
                )
            ;
    }

    qi::rule<Iterator,unsigned()> start;
};

I'm trying to understand the meaning of : roman::base_type(start).

  • I assume it is a constructor initializer.
  • Furthermore, I assume that it is a member initializer list and
    • that the member-initializer roman::base_type(start) initializes a base of roman called base_type
    • which is actually a typedef for grammar<Iterator, T1, T2, T3, T4> from which roman inherits.

What I do not understand is how it could be initialized with start when start is a member of roman, the derived class we're still constructing?


Solution

  • From the narrative around the example in the documentation:

    1. initialize the base grammar class by giving it the start rule (its the first rule that gets called when the grammar starts parsing)

    Source: http://www.boost.org/doc/libs/1_60_0/libs/spirit/doc/html/spirit/qi/tutorials/roman_numerals.html

    It's passing a reference to the member. Although the member is not constructed at this time, the reference to it is valid. Provided the base class does not dereference the reference (i.e. only stores it or takes its address) then the code is legal... if a little 'dangerous'.