Currently I have something like this:
qi::_val = boost::phoenix::bind(
[](const std::string&, const boost::optional<std::string>&)
{ return std::string();
},
qi::_1,
qi::_2
)
I would like to optionally cause this rule not to match. The documentation regarding semantic functions says nothing about how the attribute of the created object is returned.
I tried adding two additional parameters to the lambda function:
const boost::fusion::unused_type&, bool&
but this does not work.
The signatures documented here:
are low-level, shall we say "raw" semantic-action functions. They're only interesting if you're a library developer wanting to learn all the nitty gritty details about how the
Contextis statically composed, and dynamically accessed.The context contains skippers, local attributes, inherited attributes, synthesized attributes, the bound attribute reference and the parse-result flag.
Instead of dealing with these signatures, people use Phoenix expressions to create concrete semantic actions. Qi defines placeholder actors to correspond to the context elements:
You already chose Phoenix (using
phoenix::bind). So I'd recommend staying with phoenix-style actions. The simplest way to get your example to work:Bonus/Modernize
But note that you can also employ more highlevel Phoenix facilities.
I personally prefer Phoenix adapting callables. E.g. let's write a more functional semantic action:
The validation logic it implements is: if the second string is present it must match the first one in reverse.
Now, you can use
phoenix::functionto create a corresponding actor:This means you can write the action simply:
See this Live On Coliru
Output:
Observations:
Note that this way you are in no way required to take
bool& passas a parameter. Instead, you could return the bool:And write the action like:
With the exact same results.
Often you can leverage existing actors (e.g. for standard library functions and operators) and write without a custom function at all, e.g. to match a word only if followed by its length:
See it Live On Coliru
C++17 sweetness
In C++17 you can use lambdas conveniently due to CTAD. That way you can avoid defining the
magic_ftype as before:See it Live On Coliru