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

### 1137. Return type of `conj` and `proj`

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

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_type` of 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_type` of the effectively cast arguments.