[Bug libstdc++/51013] complex::{imag,real}() should maintain lvalue-returning extension in C++11

redi at gcc dot gnu.org gcc-bugzilla@gcc.gnu.org
Sun Sep 6 18:45:00 GMT 2015


https://gcc.gnu.org/bugzilla/show_bug.cgi?id=51013

--- Comment #15 from Jonathan Wakely <redi at gcc dot gnu.org> ---
(In reply to Ross Martin from comment #14)
> This change to not be able to pull out a reference to the real or imaginary
> parts has messed me up.  The assumption being made by this new complex class
> is that the real and imaginary parts are just a float or a double.

No, because if they are float or double then the corresponding explicit
specialization would be used. If the primary template is used then the type
must be some other type.

>  That is
> false in my code, and doesn't seem to be a good assumption for a
> general-purpose complex implementation.

It's what the C++ standard specifies.


>  My code has real and imaginary
> parts that are themselves full classes.  These classes can, at times, act
> like double-precision numbers, so it makes sense to build complex numbers
> out of them for arithmetic manipulations.  However, I need direct access to
> the real and imaginary parts to be able to access other parts of the class
> parameters, and this new complex-class implementation explicitly forbids any
> direct access to the real and imaginary parts in a type-safe way that
> doesn't rely on knowledge of internal class data organization.  Not a good
> change, IMHO.

Did you read http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#387 ?

Have you looked at [complex.numbers] in the C++ standard? It says exactly how
to do it:


  If z is an lvalue expression of type cv std::complex<T> then

    the expression reinterpret_cast<cv T(&)[2]>(z) is well-formed; and
    reinterpret_cast<cv T(&)[2]>(z)[0] designates the real part of z; and
    reinterpret_cast<cv T(&)[2]>(z)[1] designates the imaginary part of z.

  Moreover, if a is an expression of pointer type cv complex<T>* and the
  expression a[i] is well-defined for an integer expression i then:

    reinterpret_cast<cv T*>(a)[2*i] designates the real part of a[i]; and
    reinterpret_cast<cv T*>(a)[2*i+1] designates the imaginary part of a[i].


Rather than forbidding direct access to the real and imaginary parts the
standard explicitly requires this to work, so your concern about relying on
internal class data organization is unfounded. You can rely on it because the
standard says so.



More information about the Gcc-bugs mailing list