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)
.
roman::base_type(start)
initializes a base of roman
called base_type
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?
From the narrative around the example in the documentation:
- 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'.