Search code examples
c++c++17stdoptional

Return optional from class method


I have a optional member in a class, which I want to return by value, via a method. Sample code:

#include <stdio.h>
#include <optional>
#include <iostream>
using namespace std;

class bar {
public:
    int a;

    bar(const bar &obj) {
        a = obj.a;
    }
};

class foo {
public:
    void init(){
        abc->a = 100;
    }

    optional<bar> get() {
        return abc;
    }
    
    optional<bar> abc;
};

int main()
{
    foo temp;
    temp.init();
    auto copied = temp.get();
    cout << "Expected value is 100, got: " << copied->a;
    return 0;
}

The code outputs some garbage value.

How may I achieve this?


From my understanding, optional stores a fully allocated memory for the underlying type (not just a reference), and while returning a optional variable, the copy constructor of the underlying type should kick in, which should copy the memory as-is to the new optional value being returned.


Solution

  • You need to use the constructor of optional to ensure that it contains an object: (assuming that the redundant copy constructor of bar, which blocks it from being constructed, is removed)

    foo()
        : abc{bar{100}}
    {
    }
    

    or, after the optional has been created:

    void init(){
        abc = bar{100};
    }
    

    Otherwise, the optional is kept in an empty state, and invoking -> on an empty optional results in undefined behavior. The copy constructor of optional does not copy construct a contained object when the source is empty.