问题
Linked Question
Suppose we have:
boost::variant<nil, std::string, string_struct>
And,
struct string_struct
{
string_struct(std::string const& name = "") : name(name) {}
std::string name;
}
Is there some way to prevent the compiler from incorrectly inferring the wrong boost variant type?
More theoretically, if we had a
boost::variant<std::string, std::string>
I don't think it would compile. The first example would, however. The problem is, how do we guarantee no collision of return types? Specifically, when used as part of a parser, there are innumerable instances where we would desire the first example. So...
回答1:
This code is untested, but I am confident this will solve your problem.
struct string_struct
{
explicit string_struct(const std::string & s):name(s){}
};
typedef boost::variant<nil, std::string, string_struct> var_t;
var_t v1 = std::string("Hello");
var_t v2 = string_struct("Hello");
var1
will be unambiguously initialized to hold a string because to construct a string_struct
you have to call its constructor explicitly. var2
will, of course, be initialized to hold a string_struct because that's what you passed to the variant.
EDIT
Okay, there's a lot of type information missing about the rule(s) and struct(s) you added so I'm going to go ahead and say that those should be added to your question. I finally found the definitions in your previous question.
Disregarding that for the moment, my best guess as of right now for what you can do is to have the rule for an identifier return an actual identifier instead of a string (it is really confusing to have an identifier type and an identifier rule btw, but I realize that you're not the one who did that).
EDIT 2
Rather than post another comment, I'll put it here:
You have qi::rule<Iterator, std::string(), skipper<Iterator> > identifier;
, which declares the return type of this rule as being std::string
. Change that to qi::rule<Iterator, identifier(), skipper<Iterator> > identifier;
, which declares the return type of the rule to be an identifier
. Note the change from std::string
to identifier
. Let me know if this helps you or if you have already done that.
来源:https://stackoverflow.com/questions/34229428/how-to-get-around-matching-boost-variant-return-types