4

Is the object stored inside an instance of std::optional<T> guaranteed to be initialised in-place with placement new? This is what I would expect from most implementations, however, I can also imagine the following implementation:

/* pseudocode */ template<typename T> class optional { T object; bool has_value; }; 

In this case, when constructing an std::optional<T> that does not contain a value, T's default constructor would have to be called.
Is it guaranteed that this is not the case, and even if T does have a default constructor, it will not be called?

All I could find on cppreference related to memory management was the following: "If an optional contains a value, the value is guaranteed to be allocated as part of the optional object footprint, i.e. no dynamic memory allocation ever takes place." (https://en.cppreference.com/w/cpp/utility/optional)
However, my "implementation" above also meets this requirement.

5
  • The documentation you linked states that the only requirement on T is dectructible, so I would assume so. That wouldn't be possible unless placement new was used. Commented Jan 5, 2021 at 13:56
  • It is not constructed with new at any point. It doesn't construct the object by default. Implementations normally just reserve extra space in the class for possible future construction. Commented Jan 5, 2021 at 15:27
  • @ALX23z The question specifies placement new, and that's also how this kind of initialization works under the hood. How would you otherwise construct an object in that reserved extra space in the class that you mention? Commented Jan 5, 2021 at 19:24
  • @super oh... missed the "placement" part. Also I believe it can be done via union without placement new. Commented Jan 5, 2021 at 19:29
  • @ALX23z Probably for aggregates, but if you use classes with user-defined constructors and destructors in the union you generally need to use placement new to switch between the active members there too. So in the end you wouldn't gain much. Commented Jan 5, 2021 at 19:35

1 Answer 1

2

The standard requires that a std::optional<T> initialized either by its default constructor or its std::nullopt_t constructor does not initialize its contained T object.

From [optional.ctor] (emphasis mine):

constexpr optional() noexcept;
constexpr optional(nullopt_t) noexcept;
    Postconditions: *this does not contain a value.
    Remarks: No contained value is initialized. For every object type T these constructors are constexpr constructors ([dcl.constexpr]).

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.