Boost logo

Boost :

Subject: Re: [boost] [Conversion] Practical applications
From: Vicente J. Botet Escriba (vicente.botet_at_[hidden])
Date: 2011-08-22 18:10:37


Le 22/08/11 22:50, Phil Endecott a écrit :
> Vicente J. Botet Escriba wrote:
>> Le 21/08/11 18:18, Phil Endecott a ?crit :
>>> Dear Vicente & others,
>>>
>>> Would anyone like to share any practical or motivating applications
>>> for the proposed Boost.Conversion library?
>>>
>>> It seems to me that there are practical applications for particular
>>> types of conversion, e.g. T-to-string and string-to-T, and numeric
>>> casts, and serialisation. Apart from that, I am having trouble
>>> seeing practical reasons for generic conversion. A motivating case
>>> would be if a generic algorithm required conversion, but in the
>>> cases that I can think of either (a) the generic algorithm takes a
>>> functor, so the caller can pass the currently-required conversion as
>>> part of a lambda expression, or (b) you might need to select one of
>>> several possible conversions between a pair of types, which this
>>> library can't do, or (c) the algorithms are std:: ones which won't
>>> work with this library anyway.
>
>>
>> If we can construct implicitly a pair from another pair of implicitly
>> convertible types, why we couldn't allow the conversion from a pair
>> of type that are extrinsically implicitly convertible to them?
>
> Right. But does your library make this possible? If you could change
> std::pair, you could change that ctor to call your new conversion
> function. But you can't change std::pair. Or, have I missed
> something? (I am looking at the "Motivation" section of your docs,
> where it shows 'T t = explicit_convert_to<T>(u);' and
> 'f(implicitly(u));', etc.)
>
The specialization of the customization point implicit_convert_cp allows
to convert 'implicitly' pairs of extrinsicaly convertible types using
the implicit_convert_to function. Now the user ca use the
explicit_convert_to function to convert these types as for example

     B1 b1;
     B2 b2;
     std::pair<B1,B2> b;
     std::pair<A1,A2>
a1(boost::conversion::explicit_convert_to<std::pair<A1,A2> >(b));

Note that implicit convertible implies explicit convertible.

I wrote implicitly with coutes because we need to use a function which
makes the call explicit. But with the function implicitly we are telling
that the result is implicitly convertible to any type which is
extrinsically implicit convertible. The multiple overload example show a
morivating case on which the user can not use the implicit_convert_to<t>
to mean an implicit conversion, as implicit conversions must be implicit.

int f(int) { return 1; }
int f(std::string const&) { return 2; }

If a type T is extrinsically implicit convertible to int or std::string
the following will work

     T v;
     std::cout << f(implicitly(v)) << " called" << std::endl;

in the same way as if T were implicitly convertible to int or
std::string the following is correct

     T v;
     std::cout << f(v) << " called" << std::endl;

Resuming, the user wanting extrinsically implicit conversions, must use
explicitly the 'implicitly' function.
>
>> As part of my work, I use to be confronted to these kind of
>> situations quite often, where 3rd party libraries we use convey "the
>> same" kind of information following different and specific formats.
>
> It would be great to see some practical examples.
>
>
Yes, I know that the documentation is missing some practical examples. I
have no access now to precise examples. I would try tomorrow to recover
some more concrete examples and post them here. For the time been, let
me show you a less concrete example:

Imagine that library A defines

struct T {
   int i;
   int j;
};

and library B defines

struct R {
   long x;
   long y;
};

I magine now that you recover an array<T,3> from library A and that you
need to use some functions in library B that need a c-array R[3].

If you stablish a conversion from T to R using convert_to and if you
have that an array<T,N> can be assigned to an R[N] you could do the
following

array<T,3> source;
// call some functions in A that fill this array

A_f(source);

//Now you need to present this data to the B library
R target[3];

// convert source to target
assign_to(target,source);

// uses target in a B function

B_g(target);

We can think of the assign_to function as an algorithm that transform
the source to the target using a 'functor' that calls to convert_to on
its parts.
In order to specialize this algorithm, the user needs to specialize the
convert_to behavior instead of providing an explicit 'functor'. Note
that we can not transform heterogeneous containers using a 'functor'.

HTH,
Vicente


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