Subject: [Boost-bugs] [Boost C++ Libraries] #10839: dereferencing of rvalue optional<T&> fails due to invalid assignment of rvalue to non-const ref
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2014-12-02 19:17:01
#10839: dereferencing of rvalue optional<T&> fails due to invalid assignment of
rvalue to non-const ref
---------------------------+------------------------------
Reporter: stefan.bund@⦠| Type: Bugs
Status: new | Milestone: To Be Determined
Component: None | Version: Boost 1.57.0
Severity: Problem | Keywords:
---------------------------+------------------------------
Compiling the following code using `g++-4.9.2 -std=gnu++1y`
{{{
#include <boost/optional.hpp>
int main(int, char const **)
{
int i (0);
boost::optional<int &> opt (i);
// we use std::move here to force opt to be an rvalue. The same error
// is triggered if the optional is returned from a function call
return * std::move(opt);
}
}}}
results in the error message
> lib/boost/install/include/boost/optional/optional.hpp:1010:89: error:
invalid initialization of non-const reference of type
'boost::optional<int&>::reference_type_of_temporary_wrapper {aka int&}'
from an rvalue of type 'boost::move_detail::remove_reference<int&>::type
{aka int}'
Looking at the source code in `optional.hpp`, the culprit seems to be:
{{{
template <class T>
class optional : public optional_detail::optional_base<T>
{
// ...
reference_type_of_temporary_wrapper operator *() &&
{ return boost::move(this->get()) ; }
// ...
};
}}}
`reference_type_of_termporary_wrapper` is typedefed to `int &` as is to be
expected. If I am not mistaken, the `std::move` call however is not
correct in this case: it converts it's `int &` argument (the result of
`this->get()`) to `int &&` which is ''not'' implicitly convertible to `int
&` (the return type).
This problem only occurs with `optional<T&>` not with `optional<T const
&>` since for the latter, `reference_type_of_temporary_wrapper` is `int
const &` and `int &&` is convertible to `int const &`.
Possible resolution: If the type of the optional is a reference type,
don't apply `std::move` (e.g. add a static `move` member function to
`types_when_isnt_ref` and `types_when_is_ref` and use that member instead
of `boost::move` here).
-- Ticket URL: <https://svn.boost.org/trac/boost/ticket/10839> Boost C++ Libraries <http://www.boost.org/> Boost provides free peer-reviewed portable C++ source libraries.
This archive was generated by hypermail 2.1.7 : 2017-02-16 18:50:17 UTC