Boost logo

Boost :

Subject: Re: [boost] [conversion] ADL and templates
From: Vicente Botet (vicente.botet_at_[hidden])
Date: 2011-06-01 11:46:06

Stewart, Robert wrote:
> Vicente Botet wrote:
>> Stewart, Robert wrote:
>> > Vicente Botet wrote:
>> >
>> > namespace boost
>> > {
>> > namespace conversion
>> > {
>> > template <class Target, class Source,
>> > class Enable = void>
>> > struct converter
>> > {
>> > Target
>> > operator ()(Source const &) const;
>> > };
>> > }
>> > }
>> >
>> > Note that I'm suggesting
>> > boost::conversion::converter&lt;Target,Source,Enable&gt; as the
>> > name and I'm suggesting s/apply/operator ()/ to make it a
>> > function object. These alterations mean that there is now a
>> > function object interface for effecting conversions from
>> > Source to Target which is the sole point of customization
>> > for all such conversions in the library.
>> Yes, this could be a valid possibility. I will need to fix
>> names for the other function objects associated to assign_to
>> (assigner?), try_convert_to (try_converter), ... Or shouldn't
>> the library provide CP for all the operations?
> There should be one place to effect customization for all of the APIs
> supported by the library. The converter interface above would need to
> throw an exception to indicate a failure, so perhaps instead it should be:
> bool
> operator ()(Target &, Source const &) const;
> That would support the try API directly while those that throw an
> exception would do so if the conversion returns false. Obviously, that
> avoids the need for Target to be Copyable, if not using a wrapper function
> that requires it, but it does mean that Target must be
> DefaultConstructible or that there be a CP for providing a default value
> (as we've discussed before).

Each operation can be applied to types with different restrictions. It is
clear that convert_to can only be used for types that are CopyConstructible.
The specific implementation could have other requirements.
In particular the default one requires the expression Target(source) to be

The preceding interface corresponds to the try_assign_to function and the
interface doesn't have any requirements on the target type, except if the
target should not be modified when the conversion fails. In this case the
implementation will impose more requirements CopyConstructible. Again each
specific implementation have its owns requirements.

> Perhaps it would be better if the function object interface and the
> customization point were split:
> template &lt;class Target, class Source, class Enable = void&gt;
> struct converter
> {
> Target
> operator ()(Source const & _source) const
> {
> Target result;
> if (custom_converter&lt;Target,Source&gt;::apply(result, _source))
> {
> return result;
> }
> throw exception;
> }
> };
> template <class Target, class Source>
> struct custom_converter
> {
> static bool
> apply(Target &, Source const &);
> };

I don't think the default implementation of converter should use a function
that needs to use a try-catch block to hide the possible exception thrown
during the conversion.

> A PTS of converter that tests Enable, however you intended that to work,
> would be provided by the library, too. Both specializations would defer
> to custom_converter&lt;Target,Source&gt;::apply() to do the conversion.
> That means the CP isn't concerned with the Enable template parameter or
> with throwing exceptions.

Sorry, I don't understand what do you want to do with Enable.

> Obviously, the try API could be written to catch exceptions and return
> false while the CP could be this instead:
> static Target
> apply(Source const &);
> That permits those customizing a particular conversion to throw whatever
> exceptions they like.

This correspond to the current implementation of try_convert_to.

> I'm not sure which I prefer. The flexibility of throwing custom
> exceptions is nice, but absorbing exceptions in order to return false from
> the try API seems heavy handed.

I think we can resume that having a single customization point for all the
operations would not be enough open, and that we need CP for all the

The question now is what is the default behavior for each one of the

On the current implementation all the operations use directly or indirectly
the convert CP. I will add on the documentation the requirements for each
one of the implementations. I will use the Enable parameter each time the
requirements can be expresed using a trait meta-function.


View this message in context:
Sent from the Boost - Dev mailing list archive at

Boost list run by bdawes at, gregod at, cpdaniel at, john at