Looking at this example for implementing a Spirit parser, something caught me out when I was trying to write something similar.
The attribute template parameter of the grammar (std::map<std::string, std::string>()
) and the signature template parameter of the rules (e.g. qi::rule<Iterator, std::string()> key, value
) contain parentheses.
namespace qi = boost::spirit::qi;
template <typename Iterator>
struct keys_and_values
: qi::grammar<Iterator, std::map<std::string, std::string>()> // <- parentheses here
{
keys_and_values()
: keys_and_values::base_type(query)
{
query = pair >> *((qi::lit(';') | '&') >> pair);
pair = key >> -('=' >> value);
key = qi::char_("a-zA-Z_") >> *qi::char_("a-z开发者_JAVA技巧A-Z_0-9");
value = +qi::char_("a-zA-Z_0-9");
}
qi::rule<Iterator, std::map<std::string, std::string>()> query; // <- parentheses here
qi::rule<Iterator, std::pair<std::string, std::string>()> pair; // <- parentheses here
qi::rule<Iterator, std::string()> key, value; // <- parentheses here
};
I have never seen this before, and I unintentionally omitted then when writing my own version. This lead to my parser not generating the correct output run time (the output map is empty).
What is the purpose of these parentheses? My guess is that this makes the attribute of this rule an object of that type.
std::map<std::string, std::string>()
This is a function type.
The ()
makes this mean "a function that returns a std::map<std::string, std::string>
and has no parameters."
Without the ()
, the type is just "std::map<std::string, std::string>
," which is not correct.
精彩评论