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

### 975. `is_convertible` cannot be instantiated for non-convertible types

Section: 21.3.7 [meta.rel] Status: C++11 Submitter: Daniel Krügler Opened: 2009-01-25 Last modified: 2016-01-28

Priority: Not Prioritized

View other active issues in [meta.rel].

View all other issues in [meta.rel].

View all issues with C++11 status.

Discussion:

Addresses UK 206

Related to 1114.

The current specification of `std::is_convertible` (reference is draft N2798) is basically defined by 21.3.7 [meta.rel] p.4:

> In order to instantiate the template `is_convertible<From, To>`, the following code shall be well formed:

> >     template <class T>
> >       typename add_rvalue_reference<T>::type create();

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

> [Note: This requirement gives well defined results for reference types, void types, array types, and function types. — end note]

The first sentence can be interpreted, that e.g. the expression

>     std::is_convertible<double, int*>::value

is ill-formed because `std::is_convertible<double, int*>` could not be instantiated, or in more general terms: The wording requires that `std::is_convertible<X, Y>` cannot be instantiated for otherwise valid argument types `X` and `Y` if `X` is not convertible to `Y`.

This semantic is both unpractical and in contradiction to what the last type traits paper N2255 proposed:

> If the following `test` function is well formed code `b` is `true`, else it is `false`.

> >     template <class T>
> >       typename add_rvalue_reference<T>::type create();

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

> [Note: This definition gives well defined results for `reference` types, `void` types, array types, and function types. — end note]

[ Post Summit: ]

> Jens: Checking that code is well-formed and then returning `true`/`false` sounds like speculative compilation. John Spicer would really dislike this. Please find another wording suggesting speculative compilation.

> Recommend Open.

[ Post Summit, Howard adds: ]

> John finds the following wording clearer:

> > Template | Condition | Comments
> > --- | --- | ---
> > `template <class From, class To> struct is_convertible;` | see below | `From` and `To` shall be complete types, arrays of unknown bound, or (possibly cv-qualified) `void` types.

> > Given the following function prototype:

> > >     template <class T>
> > >       typename add_rvalue_reference<T>::type create();

> > `is_convertible<From, To>::value` shall be `true` if the return expression in the following code would be well-formed, including any implicit conversions to the return type of the function, else `is_convertible<From, To>::value` shall be `false`.

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

Original proposed wording:

In 21.3.7 [meta.rel]/4 change:

> In order to instantiate the template `is_convertible<From, To>`, the following code shall be well formed If the following code is well formed `is_convertible<From, To>::value` is `true`, otherwise `false`:[..]

Revision 2

> In 21.3.7 [meta.rel] change:

> > Template | Condition | Comments
> > --- | --- | ---
> > ... | ... | ...
> > `template <class From, class To> struct is_convertible;` | The code set out below shall be well formed. see below | `From` and `To` shall be complete types, arrays of unknown bound, or (possibly cv-qualified) `void` types.

> > -4- In order to instantiate the template `is_convertible<From, To>`, the following code shall be well formed: Given the following function prototype:

> > >     template <class T>
> > >       typename add_rvalue_reference<T>::type create();

> > `is_convertible<From, To>::value` inherits either directly or indirectly from `true_type` if the return expression in the following code would be well-formed, including any implicit conversions to the return type of the function, else `is_convertible<From, To>::value` inherits either directly or indirectly from `false_type`.

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

> > [Note: This requirement gives well defined results for reference types, void types, array types, and function types. -- end note]

[ Batavia (2009-05): ]

> We agree with the proposed resolution. Move to Tentatively Ready.

Proposed resolution:

In 21.3.7 [meta.rel] change:

> Template | Condition | Comments
> --- | --- | ---
> ... | ... | ...
> `template <class From, class To> struct is_convertible;` | The code set out below shall be well formed. see below | `From` and `To` shall be complete types, arrays of unknown bound, or (possibly cv-qualified) `void` types.

> -4- In order to instantiate the template `is_convertible<From, To>`, the following code shall be well formed: Given the following function prototype:

> >     template <class T>
> >       typename add_rvalue_reference<T>::type create();

> 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 create<From>();
> >     }

> [Note: This requirement gives well defined results for reference types, void types, array types, and function types. — end note]