Search code examples
c++boostboost-optional

Do optional references in c++ preserve object life?


Say I have:

#include <iostream>
#include "boost/optional.hpp"
struct cat
{
    int paw = 4;
};

int main()
{
    boost::optional<cat&> z;
    {
        cat realCat = cat();
        z = realCat;
    }
    std::cout << z->paw << std::endl;
    return 0;
}

In the above, there's no reason to expect a consistent result to be printed, right, as the realCat was released by }? Or does the optional preserve the life of the realCat?


Solution

  • No, it doesn't, your code has undefined behavior when you try to print the value of paw.

    The C++ rules for lifetime extension only apply when a temporary object is bound to an rvalue reference or lvalue reference to const, but realCat is not a temporary and binding it to an optional reference doesn't extend it's lifetime.

    In any case, these lifetime extension rules don't apply to boost::optional<T&>. The documentation for boost::optional mentions this:

    Rvalue references and lvalue references to const have the ability in C++ to extend the life time of a temporary they bind to. Optional references do not have this capability ...

    As for std::optional, your program would be ill-formed if you tried to create std::optional<T&>.

    [optional.syn]/1

    A program that necessitates the instantiation of template optional for a reference type, or for possibly cv-qualified types in_­place_­t or nullopt_­t is ill-formed.