Boost logo

Boost :

Subject: Re: [boost] Boost review of the Convert library is ongoing
From: Vladimir Batov (Vladimir.Batov_at_[hidden])
Date: 2014-05-22 20:25:12

On 05/22/2014 08:11 PM, alex wrote:

>> Although the code above forces
>> every converter to do that by themselves, right? Although passing
>> boost::optional into a container might have its benefits... I had it at
>> one point... will have to re-visit again.
> The benefit is that it defers initialization and thus passes that
> responsibility from the generic function to the specific converters.
>> That's something I'll have to think about. What jumps at me though is
>> what I'd call "blur of responsibilities" -- now converter not only
>> cares for conversion but for allocation as well. Secondly, in the
>> current "convert" design converters know nothing about boost::convert
>> "framework". The implementation above seems to require the converter to
>> know/deploy boost::converter_default_maker which is either part of the
>> "convert" infrastructure or converter's own code, i.e. the converter has
>> to have either additional "knowledge"/coupling or additional code. In
>> both cases I do not like the "additional" bit. :-)
> Some converters require this additional code/knowledge and others not. For
> instance, your encryption converter would probably not need it.


I snipped other comments as I'd like to focus on this one without
distractions. We might have to rewind a little bit and you might have to
repeat something... apologies.

So, it boils down to the current converter signature

template<class TypeOut, class TypeIn>
bool operator()(TypeIn const&, TypeOut&); //#1

when you suggest (if I understand correctly)

template<class TypeOut, class TypeIn>
bool operator()(TypeIn const&, boost::optional<TypeOut>&); //#2

If so, I'd take it one step further to

template<class TypeOut, class TypeIn>
boost::optional<TypeOut> operator()(TypeIn const&); //#3

#3 seems to offer all #2 does but is cleaner and idiomatic to C++. Agreed?

#3 surely seems attractive and with that interface converters can be
easily used on their own (if needed/preferred) bypassing "convert" api

Let's take a simple case of, say, the "direction" class from the docs
(which has no default constructor) and try converting it to std::string.
Say, we want that conversion possible using a few converters with
std::sstream-based being one of them. In that setting I say #1 has the
following advantages (no matter how ugly I personally find it):

1) Converters are not concerned with how to create storage for the
result and only concerned with conversion. "Converters are only
concerned with conversion" -- I like that.

2) Converters are not aware of the "convert" infrastructure.

Your example (adjusted for #3) for 2 generic converters:

template<TypeIn, TypeOut>
basic_stringstream_converter::operator()(const TypeIn& in)
     boost::optional<TypeOut> out =

     stream_.str(std::basic_string< char_type>());
     stream_ << in; stream_ >> *out;

     return out = ? boost::optional<TypeOut> : out;

template<TypeIn, TypeOut>
lexical_cast_converter::operator()(const TypeIn& in)

         boost::optional<TypeOut> out_value =
         *out_value = boost::lexical_cast<TypeOut>(in);
         return out;
     catch (...)
         return out = boost::optional<TypeOut>;

I like the signature. I do not like that #2 and #3 seem to impose all
the same requirements on TypeOut, i.e. nothing gained. I do not like
that every converter has to know about and call


Somebody has to provide that... Every container doing that by itself
sounds unreasonable. That's probably my only gripe... but it results in
losing both advantages I listed for #1. Let's try staying with
mainstream usage examples meaningful for the majority of users. I'll
unlikely be persuaded by an esoteric academic (even a real but
corner-case) example that will have negative impact on the real users.

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