Boost logo

Boost :

From: Gennaro Prota (gennaro_prota_at_[hidden])
Date: 2003-01-21 14:45:19


On Tue, 21 Jan 2003 12:58:47 -0500, David Abrahams
<dave_at_[hidden]> wrote:

>I don't think anyone thought very carefully
>about the meaning of "convertible" before, and I think we could
>probably stand to tighten up our documentation in this area. All it
>says right now is:
>
> Evaluates to true if type T is convertible to type U.
> Types T and U must not be incomplete, abstract or function types.
>
>Can you suggest an appropriate technical explanation?

This is a difficult question, either because I'm currently immersed in
entirely different issues and my mind doesn't shine in context
switching and because, regardless of the specific moment, it requires
me to understand the intent first :-) For instance the documentation
you quoted says T and U cannot be function types, but one of John
replies seems to say this was not the intent. In any case even after
understanding the intent it's difficult to come up with a definition
that doesn't involve a long list of special cases. To explain better
what I mean: suppose I look at the basic implementation

 template <typename From, typename To>
 struct is_convertible_impl
 {
     static ::boost::type_traits::no_type BOOST_TT_DECL _m_check(...);
     static ::boost::type_traits::yes_type BOOST_TT_DECL _m_check(To);
     static From _m_from;

     BOOST_STATIC_CONSTANT(bool, value =
         sizeof( _m_check(_m_from) ) ==
                  sizeof(::boost::type_traits::yes_type)
        );
 };

then I say: ok, the idea is that we say "From is convertible To" if
and only if the expression From() [5.2.3/2 of the standard] is
convertible to To. But this is not exact, for instance, when From is a
reference type because, of course, while the declaration of the member
of type From above is well-formed, the expression From() isn't. So if
I had to describe the above I should more-or-less say what the code
says:

 except for the couples (From, To) described below,
 is_convertible<From, To>::value is true if and only if
 the declaration struct X { static From f; }; is well-formed
 and the expression X::f can be implicitly converted (standard 4/3)
 to the type To.

Of course a long list should follow, including e.g. all pairs with
>From = function type. Note also that in the above I have used the
declaration struct X { static From f; }; instead of a simple From f;
because I wanted to include reference types. Alternatively I could
have said:

 except for the couples (From, To) described below,
 is_convertible<From, To>::value is true if and only if
 the declaration ** From f ** is well-formed and the expression
 f can be implicitly converted to the type To.

then of course I should have added the cases involving references to
the notorious list of "exceptions".

All in all, I don't know whether we can come up with a simple
description. But maybe that's just because I haven't followed the
original discussions about is_convertible where the fundamental idea
could have already been expressed. Another idea that may be worth
trying is to put the special cases into a table, with the regression
tests accurately reproducing the table cases:

     From: void T
     ---------------------------------
To: | |
        | |
void | false | false
        | |
T& | | true

etc.. etc... Incidentally I've noticed that currently
is_convertible<void, void> gives true. Is it the intent?

Genny.


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk