On Tue, 25 Oct 2022 at 21:15, Thiago Macieira via Std-Proposals <std-proposals@lists.isocpp.org> wrote:
On Tuesday, 25 October 2022 12:57:49 PDT Brian Bi via Std-Proposals wrote:
> If we had std::cbrt(z) for complex arguments alone, it would make sense to
> define it as std::pow(z, 1.0/3.0). But the simultaneous presence of that
> overload *and* the one for reals, such that the two do not agree when
> restricted to the real line, that would likely cause great confusion to
> programmers.

In other words, do we guarantee that

  cbrt(-1) == cbrt(-1 + 0i);

We already have sqrt(-1) != sqrt(-1 + 0i), so I'm not convinced that the confusion would be all that great.

4a) define two functions cbrt_principal (2) and cbrt_maxreal (3)
   safer solution
4b) use a second parametercbrt(double, tag)
    with tag=complex::principal_root or complex::maxreal (type, enum, ...)

Does the maxreal root have any mathematical/physical meaning, or is it just an artefact to avoid confusion on cbrt(-1 + 0i)?

5) return a list of all three roots
   caller possibly would have to sort (see above, where the position of maxreal could be any of the three)
6) return the nth root by provided index
   could lead to several repeated calls to function, which is wasteful, especially if caller has to sort the results afterwards, when looking for (3)

Presumably the implementation would derive the non-principal roots from the principal root by multiplication by the respective root of unity, so the expensive step wouldn't need to be repeated (given appropriate pure annotations).