Nishant
Nishant

Reputation: 2619

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.

Upvotes: 0

Views: 1095

Answers (2)

L. F.
L. F.

Reputation: 20579

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.

Upvotes: 4

Alan Birtles
Alan Birtles

Reputation: 36399

std::optional is like a smart pointer, it defaults to a "null" value and accessing its members would therefore be undefined behaviour. You need to initialise it before use:

void init(){
  abc = bar();
  abc->a = 100;
}

Note that as it stands bar isn't constructible other than via the copy constructor so you need to add a default constructor or a constructor that takes an int argument or remove the unnecessary copy constructor.

Upvotes: 1

Related Questions