std::complex
<complex>
class complex;
Specializations of std::complex
for cv-unqualified standard(until C++23) floating-point types are TriviallyCopyable (since C++23) LiteralTypes for representing and manipulating complex number.
Contents
[edit] Template parameters
T
is not a cv-unqualified standard(until C++23) floating-point type and undefined if T
is not NumericType.
[edit] Member types
value_type
T
[edit] Member functions
(public member function) [edit]
[edit] Non-member functions
(function template) [edit]
(function template) [edit]
(function template) [edit]
Exponential functions
(function template) [edit]
(function template) [edit]
Power functions
Trigonometric functions
(function template) [edit]
(function template) [edit]
(function template) [edit]
Hyperbolic functions
(function template) [edit]
(function template) [edit]
(function template) [edit]
(function template) [edit]
(function template) [edit]
(function template) [edit]
[edit] Helper types
(class template specialization) [edit]
[edit] Array-oriented access
For any object z of type std::complex<T>
, reinterpret_cast<T(&)[2]>(z)[0] is the real part of z and reinterpret_cast<T(&)[2]>(z)[1] is the imaginary part of z.
For any pointer to an element of an array of std::complex<T>
named p and any valid array index i, reinterpret_cast<T*>(p)[2 * i] is the real part of the complex number p[i], and reinterpret_cast<T*>(p)[2 * i + 1] is the imaginary part of the complex number p[i].
The intent of this requirement is to preserve binary compatibility between the C++ library complex number types and the C language complex number types (and arrays thereof), which have an identical object representation requirement.
[edit] Implementation notes
In order to satisfy the requirements of array-oriented access, an implementation is constrained to store the real and imaginary parts of a std::complex
specialization in separate and adjacent memory locations. Possible declarations for its non-static data members include:
- an array of type
value_type[2]
, with the first element holding the real part and the second element holding the imaginary part (e.g. Microsoft Visual Studio); - a single member of type
value_type _Complex
(encapsulating the corresponding C language complex number type) (e.g. GNU libstdc++); - two members of type
value_type
, with the same member access, holding the real and the imaginary parts respectively (e.g. LLVM libc++).
An implementation cannot declare additional non-static data members that would occupy storage disjoint from the real and imaginary parts, and must ensure that the class template specialization does not contain any padding bit. The implementation must also ensure that optimizations to array access account for the possibility that a pointer to value_type
may be aliasing a std::complex
specialization or array thereof.
[edit] Literals
std::literals::complex_literals
[edit] Notes
Feature-test macro | Value | Std | Feature |
---|---|---|---|
__cpp_lib_constexpr_complex |
201711L |
(C++20) | constexpr simple complex mathematical functions in <complex> |
202306L |
(C++26) | More constexpr for <complex> | |
__cpp_lib_tuple_like |
202311L |
(C++26) | Add tuple protocol to std::complex
|
[edit] Example
#include <cmath> #include <complex> #include <iomanip> #include <iostream> #include <ranges> int main() { using namespace std::complex_literals; std::cout << std::fixed << std::setprecision (1); std::complex<double> z1 = 1i * 1i; // imaginary unit squared std::cout << "i * i = " << z1 << '\n'; std::complex<double> z2 = std::pow (1i, 2); // imaginary unit squared std::cout << "pow(i, 2) = " << z2 << '\n'; const double PI = std::acos (-1); // or std::numbers::pi in C++20 std::complex<double> z3 = std::exp (1i * PI); // Euler's formula std::cout << "exp(i * pi) = " << z3 << '\n'; std::complex<double> z4 = 1.0 + 2i, z5 = 1.0 - 2i; // conjugates std::cout << "(1 + 2i) * (1 - 2i) = " << z4 * z5 << '\n'; const auto zz = {0.0 + 1i, 2.0 + 3i, 4.0 + 5i}; #if __cpp_lib_tuple_like >= 202311L for (double re : zz | std::views::keys ) std::cout << re << ' '; std::cout << '\n'; for (double im : zz | std::views::values ) std::cout << im << ' '; std::cout << '\n'; #else for (double re : zz | std::views::transform ([](auto z){ return z.real(); })) std::cout << re << ' '; std::cout << '\n'; for (double im : zz | std::views::transform ([](auto z){ return z.imag(); })) std::cout << im << ' '; std::cout << '\n'; #endif }
Output:
i * i = (-1.0,0.0) pow(i, 2) = (-1.0,0.0) exp(i * pi) = (-1.0,0.0) (1 + 2i) * (1 - 2i) = (5.0,0.0) 0.0 2.0 4.0 1.0 3.0 5.0
[edit] Defect reports
The following behavior-changing defect reports were applied retroactively to previously published C++ standards.
DR | Applied to | Behavior as published | Correct behavior |
---|---|---|---|
LWG 387 | C++98 | std::complex was not guaranteed to be compatible with C complex
|
guaranteed to be compatible |