boostorg / multiprecision

Boost.Multiprecision
Boost Software License 1.0
188 stars 112 forks source link

Type convertibility to `Backend` is assumed true if type is convertible to `number<Backend, et>` #608

Closed oliverlee closed 4 months ago

oliverlee commented 4 months ago

Hard error in default ops where a type V is assumed to be assignable to a backend type B.

https://godbolt.org/z/ebEj5nzvh

jzmaddock commented 4 months ago

Confirmed, we're not differentiating between number<> is constructible from V because:

1) number<> has a suitable constructor, and 2) V has a conversion operator.

(1) is handled, (2) is not and causes the error. The easiest fix (to avoid exploding the number of operator overloads), might be to disallow 2) in mixed operations. This also sort of feels like the right fix to me, what do folks think?

ckormanyos commented 4 months ago

Confirmed, we're not differentiating between number<> is constructible from V

The easiest fix (to avoid exploding the number of operator overloads), might be to disallow 2) in mixed operations. This also sort of feels like the right fix to me, what do folks think?

I played around with the overloads and found no simple fix. In the quickness of this issue, yes, a terse fix sounds better. If anything else breaks thereby, I do not know.

This is an interesting case, similar to one that I had in another, unrelated project. There I also chose to disregard the convertible case via basically the same way suggested by @jzmaddock.

ckormanyos commented 4 months ago

This stuff gets confusing when implicitly doing narrowing casts yet constructing works. It is sometimes tough to find exactly the right flavors of overloads. It's not really a help, but I've struggled whith this topic on several occasions.

Let it rip in CI and see, ... also with Math.

Cc: @mborland

oliverlee commented 4 months ago

I don't know what the implications would be allowing 2. and eagerly performing a conversion and then obtaining the backend. Disallowing 2. sounds reasonable - what would the new constraint would be?

For now, we specialize is_compatible_arithmetic_type to be false.

oliverlee commented 4 months ago

Also a better example of a wrapper type may be std::reference_wrapper

jzmaddock commented 4 months ago

This should now be addressed in develop - by addressed, I mean your example is still a compiler error because no operator overload is found, but it's the correct error now ;)