*This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of CD1 status.*

`std::complex`

over-encapsulated**Section:** 28.4 [complex.numbers] **Status:** CD1
**Submitter:** Gabriel Dos Reis **Opened:** 2002-11-08 **Last modified:** 2016-01-28

**Priority: **Not Prioritized

**View all other** issues in [complex.numbers].

**View all issues with** CD1 status.

**Discussion:**

The absence of explicit description of `std::complex<T>`

layout
makes it imposible to reuse existing software developed in traditional
languages like Fortran or C with unambigous and commonly accepted
layout assumptions. There ought to be a way for practitioners to
predict with confidence the layout of `std::complex<T>`

whenever `T`

is a numerical datatype. The absence of ways to access individual
parts of a `std::complex<T>`

object as lvalues unduly promotes
severe pessimizations. For example, the only way to change,
independently, the real and imaginary parts is to write something like

complex<T> z; // ... // set the real part to r z = complex<T>(r, z.imag()); // ... // set the imaginary part to i z = complex<T>(z.real(), i);

At this point, it seems appropriate to recall that a complex number
is, in effect, just a pair of numbers with no particular invariant to
maintain. Existing practice in numerical computations has it that a
complex number datatype is usually represented by Cartesian
coordinates. Therefore the over-encapsulation put in the specification
of `std::complex<>`

is not justified.

**Proposed resolution:**

Add the following requirements to 28.4 [complex.numbers] as 26.3/4:

If

`z`

is an lvalue expression of typecv`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 typecv`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]`

.

In 28.4.3 [complex] and [complex.special] add the following member functions
(changing `T`

to concrete types as appropriate for the specializations).

void real(T); void imag(T);

Add to 28.4.4 [complex.members]

T real() const;

Returns:the value of the real componentvoid real(T val);Assigns

`val`

to the real component.T imag() const;

Returns:the value of the imaginary componentvoid imag(T val);Assigns

`val`

to the imaginary component.

*[Kona: The layout guarantee is absolutely necessary for C
compatibility. However, there was disagreement about the other part
of this proposal: retrieving elements of the complex number as
lvalues. An alternative: continue to have real() and imag() return
rvalues, but add set_real() and set_imag(). Straw poll: return
lvalues - 2, add setter functions - 5. Related issue: do we want
reinterpret_cast as the interface for converting a complex to an
array of two reals, or do we want to provide a more explicit way of
doing it? Howard will try to resolve this issue for the next
meeting.]*

*[pre-Sydney: Howard summarized the options in n1589.]*

*[
Bellevue:
]*

Second half of proposed wording replaced and moved to Ready.

*[
Pre-Sophia Antipolis, Howard adds:
]*

Added the members to [complex.special] and changed from Ready to Review.

*[
Post-Sophia Antipolis:
]*

Moved from WP back to Ready so that the "and [complex.special]" in the proposed resolution can be officially applied.

**Rationale:**

The LWG believes that C99 compatibility would be enough justification for this change even without other considerations. All existing implementations already have the layout proposed here.