Search code examples
c++c++20copy-elisionstdoptional

Is it useful to construct an std::optional using std::in_place when returning from a function?


I was just wondering, is it useful to return an std::optional from a function constructed using std::in_place? Should I be doing it blindly or does copy elision/changing C++ versions/the data structure being trivially constructible/destructible change anything?


Solution

  • The in-place constructor is useful when a class is not copyable or movable. For example:

    #include <mutex>
    #include <optional>
    
    struct T { T(int, int); std::mutex m; };
    
    std::optional<T> f() {
        // return T(1, 2);                            // Error: T not movable
        // return std::make_optional(T(1, 2));        // Error: T not movable
        return std::optional<T>(std::in_place, 1, 2); // works
    }
    

    Otherwise, if you already have the desired return value and the type is movable, you can just use the "normal" constructor-from-type:

    T x = ...;
    // ...
    return x;
    

    It'd perhaps be a bit unusual to spell this as return std::optional<T>(std::in_place, x);, even if just because it repeats the type name unnecessarily.