Date
2018-12-09.00:00:00
Message id
10253

Content

Per Table 49 in [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.