**Section:** 28.4.9 [cmplx.over] **Status:** C++11
**Submitter:** Marc Steinbach **Opened:** 2009-06-11 **Last modified:** 2016-01-28 10:19:27 UTC

**Priority: **Not Prioritized

**View all other** issues in [cmplx.over].

**View all issues with** C++11 status.

**Discussion:**

In clause 1, the Working Draft (N2857) specifies overloads of the functions

arg, conj, imag, norm, proj, real

for non-complex arithmetic types (`float`, `double`,
`long double`, and integers).
The only requirement (clause 2) specifies effective type promotion of arguments.

I strongly suggest to add the following requirement on the return types:

All the specified overloads must return real (i.e., non-complex) values, specifically, the nested

value_typeof effectively promoted arguments.

(This has no effect on `arg`, `imag`, `norm`, `real`:
they are real-valued anyway.)

**Rationale:**

Mathematically, `conj()` and `proj()`, like the transcendental functions, are
complex-valued in general but map the (extended) real line to itself.
In fact, both functions act as identity on the reals.
A typical user will expect `conj()` and `proj()` to preserve this essential
mathematical property in the same way as `exp()`, `sin()`, etc.
A typical use of `conj()`, e.g., is the generic scalar product of n-vectors:

template<typename T> inline T scalar_product(size_t n, T const* x, T const* y) { T result = 0; for (size_t i = 0; i < n; ++i) result += x[i] * std::conj(y[i]); return result; }

This will work equally well for real and complex floating-point types `T` if
`conj()` returns `T`. It will not work with real types if `conj()`
returns complex values.

Instead, the implementation of `scalar_product` becomes either less efficient
and less useful (if a complex result is always returned), or unnecessarily
complicated (if overloaded versions with proper return types are defined).
In the second case, the real-argument overload of `conj()` cannot be used.
In fact, it must be avoided.

Overloaded `conj()` and `proj()` are principally needed in generic programming.
All such use cases will benefit from the proposed return type requirement,
in a similar way as the `scalar_product` example.
The requirement will not harm use cases where a complex return value
is expected, because of implicit conversion to complex.
Without the proposed return type guarantee, I find overloaded versions
of `conj()` and `proj()` not only useless but actually troublesome.

*[
2009-11-11 Moved to Tentatively Ready after 5 positive votes on c++std-lib.
]*

**Proposed resolution:**

Insert a new paragraph after 28.4.9 [cmplx.over]/2:

All of the specified overloads shall have a return type which is the nested

value_typeof the effectively cast arguments.