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

Section: 22.5 [optional], 22.6 [variant], 22.7 [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 22.5.3 [optional.optional], class template optional synopsis, as indicated:

    […]
    // 22.5.3.4 [optional.assign], assignment
    […]
    template <class... Args> voidT& emplace(Args&&...);
    template <class U, class... Args>
      voidT& emplace(initializer_list<U>, Args&&...);
    […]
    
  2. Modify 22.5.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 22.6.3 [variant.variant], class template variant synopsis, as indicated:

    […]
    // 22.6.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 22.6.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 22.7.4 [any.class], class any synopsis, as indicated:

    […]
    // 22.7.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 22.7.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.

    […]