This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of C++17 status.

### 2857. `{variant,optional,any}::emplace` should return the constructed value

Section: 20.6 [optional], 20.7 [variant], 20.8 [any] Status: C++17 Submitter: Zhihao Yuan Opened: 2017-01-25 Last modified: 2020-09-06

Priority: 1

View all other issues in [optional].

View all issues with C++17 status.

Discussion:

When you want to continue operate on the new contained object constructed by `emplace`, you probably don't want to go through the type-safe machinery again.

[2017-01-27 Telecon]

Priority 1; send to LEWG.

[Kona 2017-03-02]

Accepted as Immediate because P1.

Proposed resolution:

This wording is relative to N4618.

1. Update the following signatures in 20.6.3 [optional.optional], class template `optional` synopsis, as indicated:

   >     […]
   >     // 20.6.3.4 [optional.assign], assignment
   >     […]
   >     template <class... Args> voidT& emplace(Args&&...);
   >     template <class U, class... Args>
   >       voidT& emplace(initializer_list<U>, Args&&...);
   >     […]

2. Modify 20.6.3.4 [optional.assign] as indicated:

   >     template <class... Args> voidT& emplace(Args&&... args);

   > > […]

   > > -27- Postconditions: `*this` contains a value.

   > > -?- Returns: A reference to the new contained value.

   > > -28- Throws: Any exception thrown by the selected constructor of `T`.

   >     template <class U, class... Args> voidT& emplace(initializer_list<U> il, Args&&... args);

   > > […]

   > > -31- Postconditions: `*this` contains a value.

   > > -?- Returns: A reference to the new contained value.

   > > -32- Throws: Any exception thrown by the selected constructor of `T`.

3. Modify the following signatures in 20.7.3 [variant.variant], class template `variant` synopsis, as indicated:

   >     […]
   >     // 20.7.3.5 [variant.mod], modifiers
   >     template <class T, class... Args> voidT& emplace(Args&&...);
   >     template <class T, class U, class... Args>
   >       voidT& emplace(initializer_list<U>, Args&&...);
   >     template <size_t I, class... Args> voidvariant_alternative_t<I, variant<Types...>>& emplace(Args&&...);
   >     template <size_t I, class U, class... Args>
   >       voidvariant_alternative_t<I, variant<Types...>>& emplace(initializer_list<U>, Args&&...);
   >     […]

4. Modify 20.7.3.5 [variant.mod] as indicated:

   >     template <class T, class... Args> voidT& emplace(Args&&... args);

   > > -1- Effects: Equivalent to `return emplace<I>(std::forward<Args>(args)...);` where `I` is the zero-based index of `T` in `Types...`.

   > > […]

   >     template <class T, class U, class... Args>
   >       voidT& emplace(initializer_list<U> il, Args&&... args);

   > > -3- Effects: Equivalent to `return emplace<I>(il, std::forward<Args>(args)...);` where `I` is the zero-based index of `T` in `Types...`.

   > > […]

   >     template <size_t I, class... Args> voidvariant_alternative_t<I, variant<Types...>>& emplace(Args&&... args);

   > > […]

   > > -7- Postconditions: `index()` is `I`.

   > > -?- Returns: A reference to the new contained value.

   > > -8- Throws: Any exception thrown during the initialization of the contained value.

   > > […]

   >     template <size_t I, class U, class... Args>
   >       voidvariant_alternative_t<I, variant<Types...>>& emplace(initializer_list<U> il, Args&&... args);

   > > […]

   > > -12- Postconditions: `index()` is `I`.

   > > -?- Returns: A reference to the new contained value.

   > > -13- Throws: Any exception thrown during the initialization of the contained value.

   > > […]

5. Modify the following signatures in 20.8.4 [any.class], class `any` synopsis, as indicated:

   >     […]
   >     // 20.8.4.4 [any.modifiers], modifiers
   >     template <class ValueType, class... Args>
   >       voiddecay_t<ValueType>& emplace(Args&& ...);
   >     template <class ValueType, class U, class... Args>
   >       voiddecay_t<ValueType>& emplace(initializer_list<U>, Args&&...);
   >     […]

6. Modify 20.8.4.4 [any.modifiers] as indicated:

   >     template <class ValueType, class... Args>
   >       voiddecay_t<ValueType>& emplace(Args&&... args);

   > > […]

   > > -4- Postconditions: `*this` contains a value.

   > > -?- Returns: A reference to the new contained value.

   > > -5- Throws: Any exception thrown by the selected constructor of `T`.

   > > […]

   >     template <class ValueType, class U, class... Args>
   >       voiddecay_t<ValueType>& emplace(initializer_list<U> il, Args&&... args);

   > > […]

   > > -10- Postconditions: `*this` contains a value.

   > > -?- Returns: A reference to the new contained value.

   > > -11- Throws: Any exception thrown by the selected constructor of `T`.

   > > […]