
2014-02-21 9:25 GMT+01:00 Vladimir Batov
Rob Stewart
writes: On February 20, 2014 5:48:18 PM EST, Vladimir Batov
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::optionalstd::string res = convertstd::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: convertstd::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: convertstd::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