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.

### 3174. Precondition on `is_convertible` is too strong

Section: 21.3.7 [meta.rel] Status: New Submitter: Casey Carter Opened: 2018-12-09 Last modified: 2019-03-16

Priority: 3

View other active issues in [meta.rel].

View all other issues in [meta.rel].

View all issues with New status.

Discussion:

Per Table 49 in 21.3.7 [meta.rel], the preconditions for both `is_convertible<From, To>` and `is_nothrow_convertible<From, To>` are:

> `From` and `To` shall be complete types, arrays of unknown bound, or cv `void` types.

Consequently, this program fragment:

>     struct S;
>     static_assert(is_convertible_v<S, const S&>);

has undefined behavior despite that the actual behavior of `is_convertible` specified in [meta.rel]/5:

> -5- The predicate condition for a template specialization `is_convertible<From, To>` shall be satisfied if and only if the return expression in the following code would be well-formed, including any implicit conversions to the return type of the function:

> >     To test() {
> >       return declval<From>();
> >     }

> [ Note: …]

is well-formed: `declval<S>()` is an xvalue of type `S`, which certainly does implicitly convert to `const S&`. We should relax the precondition to allow this perfectly valid case (and similar cases like `is_convertible<S, S&&>`), letting the cases that would in fact be invalid fall through to the blanket "incompletely-defined object type" wording in [meta.rqmts]/5.

[2018-12-21 Reflector prioritization]

Set Priority to 3

Proposed resolution:

This wording is relative to N4791.

1. Modify Table 49 in 21.3.7 [meta.rel] as follows:

   Table 49 — Type relationship predicates
   Template | Condition | Comments
   --- | --- | ---
   […] | […] | […]
       template<class From, class To>
       struct is_convertible;
   | see below | `From` and `To` shall be a complete types, an arrays of unknown bound, or cv `void` types.
       template<class From, class To>
       struct is_nothrow_convertible;
   | `is_convertible_v<From, To>` is `true` and the conversion, as defined by `is_convertible`, is known not to throw any exceptions (7.6.2.7 [expr.unary.noexcept]) | `From` and `To` shall be a complete types, an arrays of unknown bound, or cv `void` types.
   […] | […] | […]