How should one use std::optional?

前端 未结 4 1252
情话喂你
情话喂你 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:14

    but I don't understand when I should use it or how I should use it.

    Consider when you are writing an API and you want to express that "not having a return" value is not an error. For example, you need to read data from a socket, and when a data block is complete, you parse it and return it:

    class YourBlock { /* block header, format, whatever else */ };
    
    std::optional cache_and_get_block(
        some_socket_object& socket);
    

    If the appended data completed a parsable block, you can process it; otherwise, keep reading and appending data:

    void your_client_code(some_socket_object& socket)
    {
        char raw_data[1024]; // max 1024 bytes of raw data (for example)
        while(socket.read(raw_data, 1024))
        {
            if(auto block = cache_and_get_block(raw_data))
            {
                // process *block here
                // then return or break
            }
            // else [ no error; just keep reading and appending ]
        }
    }
    

    Edit: regarding the rest of your questions:

    When is std::optional a good choice to use

    • When you compute a value and need to return it, it makes for better semantics to return by value than to take a reference to an output value (that may not be generated).

    • When you want to ensure that client code has to check the output value (whoever writes the client code may not check for error - if you attempt to use an un-initialized pointer you get a core dump; if you attempt to use an un-initialized std::optional, you get a catch-able exception).

    [...] and how does it compensate for what was not found in the previous Standard (C++11).

    Previous to C++11, you had to use a different interface for "functions that may not return a value" - either return by pointer and check for NULL, or accept an output parameter and return an error/result code for "not available".

    Both impose extra effort and attention from the client implementer to get it right and both are a source of confusion (the first pushing the client implementer to think of an operation as an allocation and requiring client code to implement pointer-handling logic and the second allowing client code to get away with using invalid/uninitialized values).

    std::optional nicely takes care of the problems arising with previous solutions.

提交回复
热议问题