How should one use std::optional?

前端 未结 4 1240
情话喂你
情话喂你 2020-12-02 04:53

I\'m reading the documentation of std::experimental::optional and I have a good idea about what it does, but I don\'t understand when I should use it or how I shoul

4条回答
  •  时光取名叫无心
    2020-12-02 05:15

    The simplest example I can think of:

    std::optional try_parse_int(std::string s)
    {
        //try to parse an int from the given string,
        //and return "nothing" if you fail
    }
    

    The same thing might be accomplished with a reference argument instead (as in the following signature), but using std::optional makes the signature and usage nicer.

    bool try_parse_int(std::string s, int& i);
    

    Another way that this could be done is especially bad:

    int* try_parse_int(std::string s); //return nullptr if fail
    

    This requires dynamic memory allocation, worrying about ownership, etc. - always prefer one of the other two signatures above.


    Another example:

    class Contact
    {
        std::optional home_phone;
        std::optional work_phone;
        std::optional mobile_phone;
    };
    

    This is extremely preferable to instead having something like a std::unique_ptr for each phone number! std::optional gives you data locality, which is great for performance.


    Another example:

    template
    class Lookup
    {
        std::optional get(Key key);
    };
    

    If the lookup doesn't have a certain key in it, then we can simply return "no value."

    I can use it like this:

    Lookup location_lookup;
    std::string location = location_lookup.get("waldo").value_or("unknown");
    

    Another example:

    std::vector> search(
        std::string query,
        std::optional max_count,
        std::optional min_match_score);
    

    This makes a lot more sense than, say, having four function overloads that take every possible combination of max_count (or not) and min_match_score (or not)!

    It also eliminates the accursed "Pass -1 for max_count if you don't want a limit" or "Pass std::numeric_limits::min() for min_match_score if you don't want a minimum score"!


    Another example:

    std::optional find_in_string(std::string s, std::string query);
    

    If the query string isn't in s, I want "no int" -- not whatever special value someone decided to use for this purpose (-1?).


    For additional examples, you could look at the boost::optional documentation. boost::optional and std::optional will basically be identical in terms of behavior and usage.

提交回复
热议问题