In <tr1_impl/complex>, GCC defines an additional overload of conj(x)
for non-complex arithmetic types, as specified in 26.3.9 [cmplx.over]
of the upcoming C++ Standard (Working Draft).
The Draft mandates certain type promotion of x.

In the (experimental) GCC implementation, conj(x) returns x as a
complex value (with imaginary part zero).

I strongly suggest to return x as a non-complex type
(specifically, the required promoted argument type).

As I read the Draft, this should satisfy the requirement of an
/effectively/ promoted argument: if needed, the returned real
will transparently be converted to complex.
(Actually I find a real return type so essential that it should be
/mandated/ by the standard. Is such a change still possible?)

Rationale:
Mathematically, complex conjugation (like the transcendental functions)
is complex-valued in general but maps the (extended) real line to itself.
A typical user will expect conj() to preserve this mathematical property,
just like exp(), sin(), etc. do.
A typical use of conj() 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 += std::conj(x[i]) * 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, a less efficient and unnecessarily complicated
scalar product implementation will be needed, e.g., using a complex
type for the temporary variable result.

Any use of conj() I can think of will benefit in this way from the proposed
change. I cannot think of any case where it would do any harm.
In contrast, I find the current overload conj() not only useless
but actually troublesome.
Or do I miss some important point?

PS: all this applies similarly to proj(x), except that it is not yet
provided by GCC.

Reply via email to