How to get around matching Boost Variant return types?

时光毁灭记忆、已成空白 提交于 2020-01-06 21:20:55

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!