mpq_class and Templated Readingmpq_class
requires a canonicalize call if inputs read with operator>>
might be non-canonical. This can lead to incorrect results.
operator>> behaves as it does for reasons of efficiency. A
canonicalize can be quite time consuming on large operands, and is best
avoided if it's not necessary.
But this potential difficulty reduces the usefulness of mpq_class.
Perhaps a mechanism to tell operator>> what to do will be adopted in
the future, maybe a preprocessor define, a global flag, or an ios flag
pressed into service. Or maybe, at the risk of inconsistency, the
mpq_class operator>> could canonicalize and leave mpq_t
operator>> not doing so, for use on those occasions when that's
acceptable. Send feedback or alternate ideas to gmp-bugs@gmplib.org.
Expressions involving subclasses resolve correctly (or seem to), but in normal
C++ fashion the subclass doesn't inherit constructors and assignments.
There's many of those in the GMP classes, and a good way to reestablish them
in a subclass is not yet provided.
T
intended to be some numeric type,
template <class T>
T fun (const T &, const T &);
When used with, say, plain mpz_class variables, it works fine: T
is resolved as mpz_class.
mpz_class f(1), g(2);
fun (f, g); // Good
But when one of the arguments is an expression, it doesn't work.
mpz_class f(1), g(2), h(3);
fun (f, g+h); // Bad
This is because g+h ends up being a certain expression template type
internal to gmpxx.h, which the C++ template resolution rules are unable
to automatically convert to mpz_class. The workaround is simply to add
an explicit cast.
mpz_class f(1), g(2), h(3);
fun (f, mpz_class(g+h)); // Good
Similarly, within fun it may be necessary to cast an expression to type
T when calling a templated fun2.
template <class T>
void fun (T f, T g)
{
fun2 (f, f+g); // Bad
}
template <class T>
void fun (T f, T g)
{
fun2 (f, T(f+g)); // Good
}
auto,
decltype, etc. While they can be very convenient, they don't mix well
with expression templates. In this example, the addition is performed twice,
as if we had defined sum as a macro.
mpz_class z = 33;
auto sum = z + z;
mpz_class prod = sum * sum;
This other example may crash, though some compilers might make it look like
it is working, because the expression z+z goes out of scope before it
is evaluated.
mpz_class z = 33;
auto sum = z + z + z;
mpz_class prod = sum * 2;
It is thus strongly recommended to avoid auto anywhere a GMP C++
expression may appear.