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

### 3697. Preconditions of `reference_constructs_from_temporary/reference_converts_from_temporary` seem wrong

Section: 21.3.5.4 [meta.unary.prop] Status: New Submitter: Jiang An Opened: 2022-05-10 Last modified: 2022-05-17

Priority: 3

View other active issues in [meta.unary.prop].

View all other issues in [meta.unary.prop].

View all issues with New status.

Discussion:

`std::reference_constructs_from_temporary` and `std::reference_converts_from_temporary` are only useful when `T` is a reference type, and a reference type is always complete. Whenever `T` is an incomplete object type, it's clear that these traits inherit from `std::false_type`, without any further detection which may result in UB. However, when `T` is `X&` or `X&&` where `X` is an incomplete object type, UB may be needed because of the potentially problematic detection in `std::is_constructible` or `std::is_convertible`.

I'm not sure whether the general rule in 21.3.2 [meta.rqmts]/5 affects these cases.

[2022-05-17; Reflector poll]

Set priority to 3 after reflector poll.

Proposed resolution:

This wording is relative to N4910.

1. Modify 21.3.3 [meta.type.synop], Table 46 ([tab:meta.unary.prop]) — "Type property predicates" — as indicated:

   > Table 46: Type property predicates [tab:meta.unary.prop]
   > Template | Condition | Preconditions
   > --- | --- | ---
   > `…`
   > `template<class T, class U> struct reference_constructs_from_temporary;` | `conjunction_v<is_reference<T>, is_constructible<T, U>>` is `true`, and the initialization `T t(VAL<U>);` binds `t` to a temporary object whose lifetime is extended (6.7.7 [class.temporary]). | If `T` is a reference type, `remove_reference_t<T>` and `U` `T` shall be a complete types, cv `void`, or an arrays of unknown bound.
   > `template<class T, class U> struct reference_converts_from_temporary;` | `conjunction_v<is_reference<T>, is_convertible<U, T>>` is `true`, and the initialization `T t = VAL<U>;` binds `t` to a temporary object whose lifetime is extended (6.7.7 [class.temporary]). | If `T` is a reference type, `remove_reference_t<T>` and `U` shall be complete types, cv `void`, or arrays of unknown bound.