If Integer should be the attribute opened by this rule, you need to declare it as:
qi::rule<Iterator, Integer()> integer;
(note the brackets). Spirit needs to use the function declaration syntax to describe the interface. It is used not only in the Spirit, but also in several other libraries (see, for example, boost :: function).
The main reason for this is that it is a nice concise way of specifying a functional interface. If you think about what a rule is, you quickly realize that it looks like a function: it can return a value (the analyzed result, i.e., the Synthesized attribute). In addition, it can take one or more arguments (inherited attributes).
A second, but small reason, is that the Spirit needs to be able to distinguish between the various parameters of the rule template. Template parameters can be specified in any order (except for an iterator), so it needs some ways to figure out what. The syntax for declaring a function is quite different from the skipper or encoding (the other two possible template parameters) to allow it to be recognized at compile time.
Let's look at your different attempts:
This can be done if you change the definition of the rule as described above.
integer = qi::int_[qi::_val = qi::_1];
_val refers to your Integer , and _1 refers to int . Therefore, you need to define an assignment operator from int in order to make this work:
struct Integer { int value; Integer& operator=(int) {...} };
In this case, you do not need to adapt your type as a Fusion sequence.
But you can write it even easier:
integer = qi::int_ >> qi::eps;
which is equivalent to 100% (eps is a trick used to convert the right-hand side into a parser sequence, which allows you to use the built-in distribution of attributes by matching the elements of your adapted Fusion sequence with the attributes of the sequence elements).
It:
integer = qi::int_[qi::_r1 = qi::_1];
will not work because _r1 refers to the first inherited attribute of the rule. However, your rule does not have nested attributes.
This will work:
integer = qi::int_[phoenix::bind(&Integer::value, qi::_val) = qi::_1];
but does not require you to adapt your type as a Fusion sequence.
And so it will be:
integer = qi::int_[phoenix::at_c<0>(qi::_val) = qi::_1];