Subject: [Boost-bugs] [Boost C++ Libraries] #10990: cpp_rational is not nothrow move constructible
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2015-02-02 21:40:39
#10990: cpp_rational is not nothrow move constructible
-------------------------------------------------+-------------------------
Reporter: Taras Morozovsky | Owner: johnmaddock
<taras.morozovsky@â¦> | Status: new
Type: Bugs | Component:
Milestone: To Be Determined | multiprecision
Version: Boost 1.57.0 | Severity: Problem
Keywords: multiprecision cpp_rational move |
constructor noexcept |
is_nothrow_move_constructible |
rational_adaptor |
-------------------------------------------------+-------------------------
boost::multiprecision::cpp_rational's move constructor is not noexcept.
This does not allow programmers to make objects containing a cpp_rational
data member nothrow move constructible. Maybe that's not a severe bug, but
an inconvenience at least.
#include <iostream>
#include <iomanip>
#include <type_traits>
#include <boost/multiprecision/cpp_int.hpp>
int main()
{
using namespace std;
using namespace boost::multiprecision;
cout << boolalpha;
cout << is_nothrow_move_constructible<cpp_int>::value << endl;
cout << is_nothrow_move_assignable<cpp_int>::value << endl;
cout << is_nothrow_move_constructible<cpp_rational>::value << endl;
cout << is_nothrow_move_assignable<cpp_rational>::value << endl;
}
Outputs:
true
true
false
true
I believe there is a problem in rational_adaptor (see
<rational_adaptor.hpp>, line 60), since its move constructor is defined as
follows:
rational_adaptor(rational_adaptor&& o) : m_value(o.m_value) {}
Here, o.m_value is treated like an lvalue despite it can be moved from.
Thus new object's m_value is copy-constructed, not move-constructed. That
does not allow cpp_rational's move constructor to be noexcept (it is
noexcept only if its backend class has a noexcept move ctor), also it may
lead to some minor loss of efficiency.
This problem can be fixed by rewriting mentioned rational_adaptor's move
constructor this way:
rational_adaptor(rational_adaptor&& o)
BOOST_NOEXCEPT_IF(noexcept(rational_type(std::declval<rational_type>())))
: m_value(static_cast<rational_type&&>(o.m_value)) {}
-- Ticket URL: <https://svn.boost.org/trac/boost/ticket/10990> 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