Closed afabri closed 1 year ago
I believe this is expected behaviour - the issue being that there are two user-defined conversions required to construct an E from an expression template - one the conversion to Rat, and one in E's constructor. This is certainly unfortunate, but I don't see an easy fix at our end right now.
@mborland : this is unrelated to the changes in rational_adaptor, I can reproduce with mpfr_float as well, it's intrinsic to the use of expression templates.
I might have a fix.
This is somewhat fixed in develop: the fix requires C++17 or later, prior to that the fix causes all sorts of issues with gcc and clang that I've been unable to fix.
This fix has been reverted as causing too many issues.
I'm going to close this as unfixable, consider:
#include <boost/multiprecision/cpp_int.hpp>
#include <cmath>
template <class Num>
struct wrapper
{
wrapper(const Num&);
};
using N = boost::multiprecision::cpp_int;
using W = wrapper<N>;
bool foo(const N&);
bool foo(const W&);
int main(int argc)
{
N n;
W w(n);
foo(n * n);
return 0;
}
If we allow expression templates to convert to all the types that class number
converts to, then this example will necessarily fail, as the call to foo
will be ambiguous: there are two paths the compiler could take, each involving one user-defined conversion.
My suggestion then, is that any class that is constructible from a number, should also be constructible from an expression template. But since expression templates are complex undocumented types, the best way to achieve that is a template constructor which is enable_If'ed on is_number_expression
:
template <class Arg, class = typename std::enable_if<boost::multiprecision::is_number_expression<Arg>::value>::type>
myclass(const Arg&);
Hope that all makes sense!
Hello,
The code below does not compile with clang (but with VC2022) and boost 1_80_0. The arithmetic expression
2 * r
becomes anexpression<..>
and that does not convert to the rational type.Is that normal behavior, or a bug.
https://gist.github.com/afabri/fcd036af9a1258b3d9d0bfd9977fd932