C++ Interface Limitations (GNU MP 6.3.0)
Description: How to install and use the GNU multiple precision arithmetic library, version 6.3.0.

### 12.6 C++ Interface Limitations ¶

`mpq_class` and Templated Reading

  A generic piece of template code probably won’t know that `mpq_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.

Subclassing

  Subclassing the GMP C++ classes works, but is not currently recommended.

  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.

Templated Expressions

  A subtle difficulty exists when using expressions together with application-defined template functions. Consider the following, with `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
      }

C++11

  C++11 provides several new ways in which types can be inferred: `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.