Boost logo

Boost :

Subject: Re: [boost] Boost.Convert. Take 2.
From: Andrzej Krzemienski (akrzemi1_at_[hidden])
Date: 2014-02-21 03:56:44


2014-02-21 9:25 GMT+01:00 Vladimir Batov <vb.mail.247_at_[hidden]>:

> Rob Stewart <robertstewart <at> comcast.net> writes:
> > On February 20, 2014 5:48:18 PM EST, Vladimir Batov <Vladimir.Batov <at>
> constrainttec.com> wrote:
> > >On 02/21/2014 02:47 AM, Andrzej Krzemienski wrote:
> > >>
> > >> Regarding "Type Requirements" section in documentation:
> > >> TypeOut needs to be
> > >>
> > >> *Copy Constructible.*
> > >> Is it not enough to require that TypeOut be *MoveConstructible*?
> > > ...
> > >Still I suspect some interfaces require to be Copy Constrictible. For
> > >example,
> > >
> > >template<typename TypeOut>
> > >struct boost::convert<TypeOut>::result
> > >{
> > > ...
> > > template<typename FallbackType>
> > > out_type value_or(FallbackType const& fallback) const
> > > {
> > > return good_ ? value_ : fallback;
> > > }
> > >};
> >
> > This would address your concern:
> >
> > if (good_)
> > {
> > return std::move(value_);
> > }
> > else
> > {
> > return fallback;
> > }
> >
> > However, for non-movable types, the fallback is to copy anyway,
> > so both should be moved.
>
> The problem is, I think, with
>
> > return std::move(value_);
>
> because it destroys "value_" which in general terms I do not think we can
> do. For example, (I'll use tr1::optional instead of convert<T>::result):
>
> tr1::optional<std::string> res = convert<std::string>::from(12345, cnv);
> std::string str = res.value_or("bummer");
>
> ... if value_or() moves/destroys the string inside "res",
> ... then "res" is not usable from here downwards
> ... it's a problem, isn't it?
>

If you added MoveConstructible requirement (I am not saying you should, I
am just exploring the possibility), you would be probably saying "It also
works with non-CopyConstructible but MoveConstructible types, but in that
case there is a limited number of ways Boost.Convert's interface can be
used." The above example would not work, but the following one should:

convert<std::string>::from(12345, cnv).value_or("bummer");

That is, you do not care that a temporary's internal value is moved from.
But this may not be implementable in C++03. I guess we do not know how to
emulate rvalue references for *this. However, the following should be easy
to implement:

convert<std::string>::from(12345, cnv).value();

For some background, move semantics obtained a nice language support in
C++11, but it is also available in C++03 for some extent. This is why we
have Boost.Move. I will try to add move semantics to Boost.Optional, so
that you can use it.

Regards,
&rzej


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