Something went wrong. Try again.
A Tour of C++ for experienced programmers, as if C++26 is the only version that ever existed.
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360<!DOCTYPE HTML><html lang="en" class="light sidebar-visible" dir="ltr"> <head> <!-- Book generated using mdBook --> <meta charset="UTF-8"> <title>Numerics and multi-dimensional data - A Tour of C++26</title>
<!-- Custom HTML head -->
<meta name="description" content=""> <meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="theme-color" content="#ffffff">
<link rel="icon" href="favicon-de23e50b.svg"> <link rel="shortcut icon" href="favicon-8114d1fc.png"> <link rel="stylesheet" href="css/variables-8adf115d.css"> <link rel="stylesheet" href="css/general-e96d0476.css"> <link rel="stylesheet" href="css/chrome-d279d366.css"> <link rel="stylesheet" href="css/print-9e4910d8.css" media="print">
<!-- Fonts --> <link rel="stylesheet" href="fonts/fonts-9644e21d.css">
<!-- Highlight.js Stylesheets --> <link rel="stylesheet" id="mdbook-highlight-css" href="highlight-493f70e1.css"> <link rel="stylesheet" id="mdbook-tomorrow-night-css" href="tomorrow-night-4c0ae647.css"> <link rel="stylesheet" id="mdbook-ayu-highlight-css" href="ayu-highlight-3fdfc3ac.css">
<!-- Custom theme stylesheets -->
<!-- Provide site root and default themes to javascript --> <script> const path_to_root = ""; const default_light_theme = "light"; const default_dark_theme = "navy"; window.path_to_searchindex_js = "searchindex-7c7963f3.js"; </script> <!-- Start loading toc.js asap --> <script src="toc-0eddcac6.js"></script> </head> <body> <div id="mdbook-help-container"> <div id="mdbook-help-popup"> <h2 class="mdbook-help-title">Keyboard shortcuts</h2> <div> <p>Press <kbd>←</kbd> or <kbd>→</kbd> to navigate between chapters</p> <p>Press <kbd>S</kbd> or <kbd>/</kbd> to search in the book</p> <p>Press <kbd>?</kbd> to show this help</p> <p>Press <kbd>Esc</kbd> to hide this help</p> </div> </div> </div> <div id="mdbook-body-container"> <!-- Work around some values being stored in localStorage wrapped in quotes --> <script> try { let theme = localStorage.getItem('mdbook-theme'); let sidebar = localStorage.getItem('mdbook-sidebar');
if (theme.startsWith('"') && theme.endsWith('"')) { localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1)); }
if (sidebar.startsWith('"') && sidebar.endsWith('"')) { localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1)); } } catch (e) { } </script>
<!-- Set the theme before any content is loaded, prevents flash --> <script> const default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? default_dark_theme : default_light_theme; let theme; try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { } if (theme === null || theme === undefined) { theme = default_theme; } const html = document.documentElement; html.classList.remove('light') html.classList.add(theme); html.classList.add("js"); </script>
<input type="checkbox" id="mdbook-sidebar-toggle-anchor" class="hidden">
<!-- Hide / unhide sidebar before it is displayed --> <script> let sidebar = null; const sidebar_toggle = document.getElementById("mdbook-sidebar-toggle-anchor"); if (document.body.clientWidth >= 1080) { try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { } sidebar = sidebar || 'visible'; } else { sidebar = 'hidden'; sidebar_toggle.checked = false; } if (sidebar === 'visible') { sidebar_toggle.checked = true; } else { html.classList.remove('sidebar-visible'); } </script>
<nav id="mdbook-sidebar" class="sidebar" aria-label="Table of contents"> <!-- populated by js --> <mdbook-sidebar-scrollbox class="sidebar-scrollbox"></mdbook-sidebar-scrollbox> <noscript> <iframe class="sidebar-iframe-outer" src="toc.html"></iframe> </noscript> <div id="mdbook-sidebar-resize-handle" class="sidebar-resize-handle"> <div class="sidebar-resize-indicator"></div> </div> </nav>
<div id="mdbook-page-wrapper" class="page-wrapper">
<div class="page"> <div id="mdbook-menu-bar-hover-placeholder"></div> <div id="mdbook-menu-bar" class="menu-bar sticky"> <div class="left-buttons"> <label id="mdbook-sidebar-toggle" class="icon-button" for="mdbook-sidebar-toggle-anchor" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="mdbook-sidebar"> <span class=fa-svg><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Free 6.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2022 Fonticons, Inc. --><path d="M0 96C0 78.3 14.3 64 32 64H416c17.7 0 32 14.3 32 32s-14.3 32-32 32H32C14.3 128 0 113.7 0 96zM0 256c0-17.7 14.3-32 32-32H416c17.7 0 32 14.3 32 32s-14.3 32-32 32H32c-17.7 0-32-14.3-32-32zM448 416c0 17.7-14.3 32-32 32H32c-17.7 0-32-14.3-32-32s14.3-32 32-32H416c17.7 0 32 14.3 32 32z"/></svg></span> </label> <button id="mdbook-theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="mdbook-theme-list"> <span class=fa-svg><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><!--! Font Awesome Free 6.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2022 Fonticons, Inc. --><path d="M371.3 367.1c27.3-3.9 51.9-19.4 67.2-42.9L600.2 74.1c12.6-19.5 9.4-45.3-7.6-61.2S549.7-4.4 531.1 9.6L294.4 187.2c-24 18-38.2 46.1-38.4 76.1L371.3 367.1zm-19.6 25.4l-116-104.4C175.9 290.3 128 339.6 128 400c0 3.9 .2 7.8 .6 11.6c1.8 17.5-10.2 36.4-27.8 36.4H96c-17.7 0-32 14.3-32 32s14.3 32 32 32H240c61.9 0 112-50.1 112-112c0-2.5-.1-5-.2-7.5z"/></svg></span> </button> <ul id="mdbook-theme-list" class="theme-popup" aria-label="Themes" role="menu"> <li role="none"><button role="menuitem" class="theme" id="mdbook-theme-default_theme">Auto</button></li> <li role="none"><button role="menuitem" class="theme" id="mdbook-theme-light">Light</button></li> <li role="none"><button role="menuitem" class="theme" id="mdbook-theme-rust">Rust</button></li> <li role="none"><button role="menuitem" class="theme" id="mdbook-theme-coal">Coal</button></li> <li role="none"><button role="menuitem" class="theme" id="mdbook-theme-navy">Navy</button></li> <li role="none"><button role="menuitem" class="theme" id="mdbook-theme-ayu">Ayu</button></li> </ul> <button id="mdbook-search-toggle" class="icon-button" type="button" title="Search (`/`)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="/ s" aria-controls="mdbook-searchbar"> <span class=fa-svg><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Free 6.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2022 Fonticons, Inc. --><path d="M416 208c0 45.9-14.9 88.3-40 122.7L502.6 457.4c12.5 12.5 12.5 32.8 0 45.3s-32.8 12.5-45.3 0L330.7 376c-34.4 25.2-76.8 40-122.7 40C93.1 416 0 322.9 0 208S93.1 0 208 0S416 93.1 416 208zM208 352c79.5 0 144-64.5 144-144s-64.5-144-144-144S64 128.5 64 208s64.5 144 144 144z"/></svg></span> </button> </div>
<h1 class="menu-title">A Tour of C++26</h1>
<div class="right-buttons"> <a href="print.html" title="Print this book" aria-label="Print this book"> <span class=fa-svg id="print-button"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Free 6.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2022 Fonticons, Inc. --><path d="M128 0C92.7 0 64 28.7 64 64v96h64V64H354.7L384 93.3V160h64V93.3c0-17-6.7-33.3-18.7-45.3L400 18.7C388 6.7 371.7 0 354.7 0H128zM384 352v32 64H128V384 368 352H384zm64 32h32c17.7 0 32-14.3 32-32V256c0-35.3-28.7-64-64-64H64c-35.3 0-64 28.7-64 64v96c0 17.7 14.3 32 32 32H64v64c0 35.3 28.7 64 64 64H384c35.3 0 64-28.7 64-64V384zm-16-88c-13.3 0-24-10.7-24-24s10.7-24 24-24s24 10.7 24 24s-10.7 24-24 24z"/></svg></span> </a>
</div> </div>
<div id="mdbook-search-wrapper" class="hidden"> <form id="mdbook-searchbar-outer" class="searchbar-outer"> <div class="search-wrapper"> <input type="search" id="mdbook-searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="mdbook-searchresults-outer" aria-describedby="searchresults-header"> <div class="spinner-wrapper"> <span class=fa-svg id="fa-spin"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Free 6.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2022 Fonticons, Inc. --><path d="M304 48c0-26.5-21.5-48-48-48s-48 21.5-48 48s21.5 48 48 48s48-21.5 48-48zm0 416c0-26.5-21.5-48-48-48s-48 21.5-48 48s21.5 48 48 48s48-21.5 48-48zM48 304c26.5 0 48-21.5 48-48s-21.5-48-48-48s-48 21.5-48 48s21.5 48 48 48zm464-48c0-26.5-21.5-48-48-48s-48 21.5-48 48s21.5 48 48 48s48-21.5 48-48zM142.9 437c18.7-18.7 18.7-49.1 0-67.9s-49.1-18.7-67.9 0s-18.7 49.1 0 67.9s49.1 18.7 67.9 0zm0-294.2c18.7-18.7 18.7-49.1 0-67.9S93.7 56.2 75 75s-18.7 49.1 0 67.9s49.1 18.7 67.9 0zM369.1 437c18.7 18.7 49.1 18.7 67.9 0s18.7-49.1 0-67.9s-49.1-18.7-67.9 0s-18.7 49.1 0 67.9z"/></svg></span> </div> </div> </form> <div id="mdbook-searchresults-outer" class="searchresults-outer hidden"> <div id="mdbook-searchresults-header" class="searchresults-header"></div> <ul id="mdbook-searchresults"> </ul> </div> </div>
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM --> <script> document.getElementById('mdbook-sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible'); document.getElementById('mdbook-sidebar').setAttribute('aria-hidden', sidebar !== 'visible'); Array.from(document.querySelectorAll('#mdbook-sidebar a')).forEach(function(link) { link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1); }); </script>
<div id="mdbook-content" class="content"> <main> <h1 id="numerics-and-multidimensional-views"><a class="header" href="#numerics-and-multidimensional-views">Numerics and multidimensional views</a></h1><h2 id="typesafe-math-constants-stdnumbers"><a class="header" href="#typesafe-math-constants-stdnumbers">Type‑safe math constants: <code>std::numbers</code></a></h2><p>The header <code><numbers></code> supplies <code>inline constexpr</code> constants for <code>float</code>, <code>double</code>, and <code>long double</code>. The primary name, e.g. <code>std::numbers::pi</code>, denotes a <code>double</code>. The alias <code>std::numbers::pi_v<T></code> yields the constant in type <code>T</code>. This removes the need for separate literals such as <code>M_PI</code> or user‑defined <code>constexpr</code> values.</p><p>The older macro <code>M_PI</code> originates from the C header <code><cmath></code>. It expands to a literal of type <code>double</code> and is not guaranteed to exist on all platforms. Because it is a macro, the constant cannot participate in overload resolution based on the target type. The <code>std::numbers</code> objects avoid those problems and can be used in all constexpr expressions.</p><p>The family includes more than π. <code>std::numbers::e</code>, <code>std::numbers::sqrt2</code>, <code>std::numbers::ln2</code>, and <code>std::numbers::phi</code> cover the constants most numerical code needs. The <code>_v</code> alias keeps the chosen precision: <code>std::numbers::pi_v<float></code> is a single-precision approximation, while <code>std::numbers::pi_v<long double></code> carries the widest precision the platform supports. Because the constants are <code>constexpr</code>, they can initialise <code>static</code> and <code>consteval</code> contexts without a runtime cost.</p><p>The header also provides reciprocals such as <code>std::numbers::inv_pi</code> and <code>std::numbers::inv_sqrt2</code>, which avoid a division at the call site when an inverse is what the math requires.</p><p>The example below prints the value of π, computes the area of a circle with radius <code>2.5</code>, and formats the result with <code>std::cout</code>. The test harness checks that the output contains the word <code>area</code>.</p><pre><code class="language-cpp">#include <iostream>#include <numbers>
int main(){ double r = 2.5; double area = std::numbers::pi * r * r; std::cout << "area = " << area << std::endl; return 0;}</code></pre><h2 id="core-floatingpoint-utilities-cmath"><a class="header" href="#core-floatingpoint-utilities-cmath">Core floating‑point utilities: <code><cmath></code></a></h2><p>The header <code><cmath></code> implements the classic mathematical functions. All functions are overloaded for <code>float</code>, <code>double</code>, and <code>long double</code>. Since C++26 the overload set also accepts integral arguments, promoting them to the appropriate floating type.</p><ul><li><code>std::sqrt(x)</code> returns the square root of <em>x</em>.</li><li><code>std::pow(b, e)</code> raises <em>b</em> to the power <em>e</em>.</li><li><code>std::hypot(x, y)</code> computes <code>√(x² + y²)</code> while protecting against overflow and underflow. The expression <code>std::sqrt(x*x + y*y)</code> can overflow when the magnitude of <em>x</em> or <em>y</em> is large.</li><li><code>std::floor(x)</code> returns the greatest integer not larger than <em>x</em>.</li><li><code>std::ceil(x)</code> returns the smallest integer not smaller than <em>x</em>.</li></ul><p>The set also contains safer primitives for interpolation and rounding. <code>std::midpoint(a, b)</code> returns the value halfway between <code>a</code> and <code>b</code> without the overflow that <code>a + (b - a) / 2</code> can suffer. <code>std::lerp(a, b, t)</code> computes <code>a + t * (b - a)</code> with proper endpoint handling. <code>std::fma(x, y, z)</code> computes <code>(x * y) + z</code> as a single fused operation, avoiding an intermediate rounding step and improving speed and accuracy on supporting hardware.</p><p>The classification functions <code>std::isfinite</code>, <code>std::isnan</code>, and <code>std::isinf</code> test a value’s category without throwing, which provides a reliable way to detect a failed computation.</p><p>In addition, <code>std::copysign(x, y)</code> copies the sign of <code>y</code> onto the magnitude of <code>x</code>, which is the correct way to negate a zero or to preserve a sign across an operation. <code>std::nextafter(x, y)</code> steps to the next representable value toward <code>y</code>, exposing the discrete nature of floating-point for tolerance and unit-test work.</p><p>In the following program we compute a right‑angled triangle with legs <code>3</code> and <code>4</code>. The call to <code>std::hypot</code> yields <code>5</code> without intermediate overflow. The test expects the line <code>hypot = 5</code>.</p><pre><code class="language-cpp">#include <iostream>#include <cmath>int main(){ double a = 3.0, b = 4.0; double h = std::hypot(a, b); std::cout << "hypot = " << static_cast<int>(h) << std::endl; return 0;}</code></pre><h2 id="complex-arithmetic-stdcomplex"><a class="header" href="#complex-arithmetic-stdcomplex">Complex arithmetic: <code>std::complex</code></a></h2><p>The class template <code>std::complex<T></code> stores a complex number whose real and imaginary parts are of type <code>T</code>. Member functions <code>real()</code> and <code>imag()</code> provide access to the components. The standard library overloads the arithmetic operators so that addition, subtraction, multiplication, and division operate component‑wise.</p><p>Two helper functions are useful for magnitude calculations. <code>std::norm(z)</code> returns the squared magnitude (<code>real(z)² + imag(z)²</code>). <code>std::abs(z)</code> returns the magnitude itself (<code>√norm(z)</code>). The factory function <code>std::polar(r, θ)</code> constructs a complex number from polar coordinates, where <code>r</code> is the radius and <code>θ</code> the angle in radians.</p><p>The library also overloads the transcendental functions for <code>std::complex</code>, so <code>std::sin</code>, <code>std::exp</code>, and <code>std::log</code> accept complex arguments and return complex results. <code>std::conj(z)</code> returns the conjugate, and <code>std::proj(z)</code> returns the projection onto the Riemann sphere, which matters for infinities. Only <code>std::complex<float></code>, <code>std::complex<double></code>, and <code>std::complex<long double></code> are well formed. Instantiating <code>std::complex<int></code> is ill formed, because integer complex arithmetic is not defined by the standard.</p><p>A user-defined literal makes complex literals readable. The <code>std::literals::complex_literals</code> inline namespace provides the <code>i</code> suffix, so <code>auto z = 1.0 + 2.0i</code> builds <code>1 + 2i</code> without a constructor call. The literal works for <code>float</code>, <code>double</code>, and <code>long double</code>.</p><p>The program below constructs a complex number <code>z = 3 + 4i</code>, prints its real and imaginary parts, computes its magnitude with <code>std::abs</code>, and creates a second complex number via <code>std::polar</code>. The test looks for the word <code>real</code> in the output.</p><pre><code class="language-cpp">#include <iostream>#include <complex>#include <numbers>
int main(){ std::complex<double> z(3.0, 4.0); std::cout << "real = " << z.real() << ", imag = " << z.imag() << std::endl; std::cout << "abs = " << std::abs(z) << std::endl; auto p = std::polar(2.0, std::numbers::pi/4); std::cout << "polar real = " << p.real() << std::endl; return 0;}</code></pre><h2 id="compiletime-rational-numbers-stdratio"><a class="header" href="#compiletime-rational-numbers-stdratio">Compile‑time rational numbers: <code>std::ratio</code></a></h2><p><code>std::ratio<N, D></code> encodes a rational number as two compile‑time integer template arguments. The type can be used in non‑type template parameters, which enables compile‑time arithmetic without additional run‑time cost.</p><p>The library provides metafunctions such as <code>std::ratio_add<A, B></code> and <code>std::ratio_multiply<A, B></code>. These compute a new <code>std::ratio</code> that represents the sum or product of the two operand ratios. The result is available as a nested <code>type</code> member.</p><p><code>std::ratio</code> is the foundation of the <code><chrono></code> duration type. <code>std::chrono::milliseconds</code> is <code>std::chrono::duration<int, std::ratio<1, 1000>></code>, so a ratio literal becomes a unit of time. The trait <code>std::ratio_equal<A, B></code> and the ordering <code>std::ratio_less<A, B></code> let templates reason about the relationship between two ratios at compile time, and <code>std::ratio_divide<A, B></code> produces the quotient. All of these are <code>constexpr</code>, so the compiler evaluates them entirely during compilation.</p><p>For example, <code>std::chrono::duration<long, std::ratio<1, 1000>></code> is exactly milliseconds: a duration that stores a count of <code>long</code> ticks where each tick is one thousandth of a second. Swapping the ratio to <code>std::ratio<1, 1></code> yields seconds and to <code>std::ratio<60, 1></code> yields minutes, all from the same template.</p><p>The example defines a base ratio representing one thousandth (<code>std::ratio<1, 1000></code>), prints its numerator and denominator, and then uses <code>std::ratio_add</code> to add two such ratios, which produces <code>2/1000</code>. The test harness searches for the exact string <code>1/1000</code>.</p><pre><code class="language-cpp">#include <iostream>#include <ratio>
int main(){ using thousand = std::ratio<1,1000>; std::cout << thousand::num << '/' << thousand::den << std::endl; using sum = std::ratio_add<thousand, thousand>::type; // sum is 2/1000, but we only need to show the base ratio (void)sum{}; // suppress unused warning return 0;}</code></pre><h2 id="integer-helpers-stdgcd-and-stdlcm"><a class="header" href="#integer-helpers-stdgcd-and-stdlcm">Integer helpers: <code>std::gcd</code> and <code>std::lcm</code></a></h2><p>The functions <code>std::gcd(a, b)</code> and <code>std::lcm(a, b)</code> compute the greatest common divisor and the least common multiple of two integral values. Implementations use highly optimized code to execute the Euclidean algorithm efficiently. Writing these algorithms manually can produce slower code.</p><p>The binary Euclidean algorithm runs in logarithmic time, so even 64-bit arguments complete in a few dozen cycles.</p><p>Both functions are <code>constexpr</code> and return the common type of their arguments after the usual arithmetic conversions. <code>std::gcd</code> is the building block for reducing fractions and for the Euclidean distance checks used in number theory, while <code>std::lcm</code> sizes a buffer that must hold a whole number of repeats of two periodic signals. Reaching for the standard functions avoids the off-by-one and signedness bugs that hand-written versions attract.</p><p>The program below calculates <code>gcd(48, 180)</code> and <code>lcm(48, 180)</code>. The expected output contains the two lines <code>gcd = 12</code> and <code>lcm = 720</code>.</p><pre><code class="language-cpp">#include <iostream>#include <numeric>
int main(){ int a = 48, b = 180; std::cout << "gcd = " << std::gcd(a, b) << std::endl; std::cout << "lcm = " << std::lcm(a, b) << std::endl; return 0;}</code></pre><h2 id="multidimensional-nonowning-views-stdmdspan"><a class="header" href="#multidimensional-nonowning-views-stdmdspan">Multidimensional non‑owning views: <code>std::mdspan</code></a></h2><p><code>std::mdspan</code> is a non‑owning view that maps a contiguous block of memory to a multi‑dimensional array. It extends <code>std::span</code> to support a compile‑time known number of dimensions. The template parameters are the element type and an <code>extents</code> description, which can be static, dynamic, or mixed.</p><p>Two layout policies exist. <code>std::layout_right</code> stores elements in row‑major order, which matches the layout of C‑style arrays and of <code>std::vector</code>. <code>std::layout_left</code> stores elements in column‑major order, which aligns with the conventions of Fortran and some linear‑algebra libraries. The layout determines the stride that the view applies when a multidimensional index is supplied.</p><p>The extents can be dynamic instead of static. <code>std::extents<std::size_t, std::dynamic_extent, 4></code> fixes only the column count and takes the row count at construction, which suits matrices whose size is known at runtime. <code>submdspan</code> slices a view into a smaller view without copying, mirroring <code>std::span::subspan</code> from chapter 11. The accessor template argument controls how elements are read and written, so an <code>mdspan</code> can present a strided or even a non-contiguous layout while keeping the same multidimensional interface.</p><p>Because <code>mdspan</code> is the multidimensional sibling of <code>std::span</code>, the same rule from chapter 11 applies. The view borrows storage and must not outlive the container it observes, or the indexed access reads freed memory.</p><p>Like <code>std::span</code>, <code>mdspan</code> is <code>constexpr</code> friendly, so a small matrix held in static storage can be indexed inside a <code>consteval</code> context and checked by <code>static_assert</code>.</p><p>The example creates a <code>std::vector<double></code> with twelve values. It then constructs a <code>std::mdspan<double, std::extents<std::size_t, 3, 4>, std::layout_right></code> that views the vector as a 3 × 4 matrix. A nested loop prints each row on a separate line. The test verifies the three rows <code>0 1 2 3</code>, <code>4 5 6 7</code>, and <code>8 9 10 11</code>.</p><pre><code class="language-cpp">#include <iostream>#include <vector>#include <mdspan>
int main(){ std::vector<double> data(12); for (std::size_t i = 0; i < data.size(); ++i) data[i] = static_cast<double>(i); std::mdspan<double, std::extents<std::size_t, 3, 4>, std::layout_right> view(data.data()); for (std::size_t r = 0; r < 3; ++r) { for (std::size_t c = 0; c < 4; ++c) { std::size_t idx = r * 4 + c; // row‑major stride std::cout << *(view.data_handle() + idx); if (c + 1 < 4) std::cout << ' '; } if (r + 1 < 3) std::cout << '\n'; } return 0;}</code></pre><h2 id="linear-algebra-stdlinalg-c26"><a class="header" href="#linear-algebra-stdlinalg-c26">Linear algebra: <code>std::linalg</code> (C++26)</a></h2><p>The header <code><linalg></code> adds a lightweight linear‑algebra library that operates directly on <code>std::mdspan</code> objects. Matrix‑matrix, matrix‑vector, and vector‑vector products are expressed as free functions that accept <code>std::mdspan</code> parameters. Because the functions work on views, no temporary storage is required.</p><p>Unlike the decades-old BLAS interface, <code>std::linalg</code> is generic over the element type and the layout, so the same call works on <code>float</code>, <code>double</code>, or a custom accumulator, and on row-major or column-major storage without rewriting.</p><p>All operations are <code>constexpr</code> where the underlying arithmetic permits compile‑time evaluation. This enables static analysis of small linear‑algebra expressions and permits their use in <code>static_assert</code> statements.</p><p>Support for <code><linalg></code> is not yet present in the default Clang toolchain used by the build pipeline. The book therefore presents the feature in prose only, with a callout that states the feature is a new addition in C++26 and will become available when compilers implement the header. Consequently, any example that includes <code><linalg></code> fails to compile until the compiler ships the header.</p><p>The functions follow a consistent naming pattern. <code>linalg::matrix_product</code>, <code>linalg::dot</code>, and <code>linalg::vector_norm</code> take read-only input views and an output view, returning the result through the last argument rather than by value. This output-parameter style keeps the operation allocation free and lets the caller choose the storage.</p><h2 id="try-this"><a class="header" href="#try-this">Try this</a></h2><p>Create a <code>std::vector<double></code> that contains twelve values of your choice. View the vector as a 3 × 4 <code>std::mdspan</code>. Print the element at row 1, column 2 using the call syntax <code>mdspan(r, c)</code>. Verify that the printed value matches the element you stored.</p>
</main>
<nav class="nav-wrapper" aria-label="Page navigation"> <!-- Mobile navigation buttons --> <a rel="prev" href="ch14-callables-type-erasure.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left"> <span class=fa-svg><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><!--! Font Awesome Free 6.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2022 Fonticons, Inc. --><path d="M41.4 233.4c-12.5 12.5-12.5 32.8 0 45.3l160 160c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3L109.3 256 246.6 118.6c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0l-160 160z"/></svg></span> </a>
<a rel="next prefetch" href="ch16-templates-functions.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right"> <span class=fa-svg><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><!--! Font Awesome Free 6.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2022 Fonticons, Inc. --><path d="M278.6 233.4c12.5 12.5 12.5 32.8 0 45.3l-160 160c-12.5 12.5-32.8 12.5-45.3 0s-12.5-32.8 0-45.3L210.7 256 73.4 118.6c-12.5-12.5-12.5-32.8 0-45.3s32.8-12.5 45.3 0l160 160z"/></svg></span> </a>
<div style="clear: both"></div> </nav> </div> </div>
<nav class="nav-wide-wrapper" aria-label="Page navigation"> <a rel="prev" href="ch14-callables-type-erasure.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left"> <span class=fa-svg><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><!--! Font Awesome Free 6.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2022 Fonticons, Inc. --><path d="M41.4 233.4c-12.5 12.5-12.5 32.8 0 45.3l160 160c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3L109.3 256 246.6 118.6c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0l-160 160z"/></svg></span> </a>
<a rel="next prefetch" href="ch16-templates-functions.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right"> <span class=fa-svg><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><!--! Font Awesome Free 6.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2022 Fonticons, Inc. --><path d="M278.6 233.4c12.5 12.5 12.5 32.8 0 45.3l-160 160c-12.5 12.5-32.8 12.5-45.3 0s-12.5-32.8 0-45.3L210.7 256 73.4 118.6c-12.5-12.5-12.5-32.8 0-45.3s32.8-12.5 45.3 0l160 160z"/></svg></span> </a> </nav>
</div>
<template id=fa-eye><span class=fa-svg><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><!--! Font Awesome Free 6.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2022 Fonticons, Inc. --><path d="M288 32c-80.8 0-145.5 36.8-192.6 80.6C48.6 156 17.3 208 2.5 243.7c-3.3 7.9-3.3 16.7 0 24.6C17.3 304 48.6 356 95.4 399.4C142.5 443.2 207.2 480 288 480s145.5-36.8 192.6-80.6c46.8-43.5 78.1-95.4 93-131.1c3.3-7.9 3.3-16.7 0-24.6c-14.9-35.7-46.2-87.7-93-131.1C433.5 68.8 368.8 32 288 32zM432 256c0 79.5-64.5 144-144 144s-144-64.5-144-144s64.5-144 144-144s144 64.5 144 144zM288 192c0 35.3-28.7 64-64 64c-11.5 0-22.3-3-31.6-8.4c-.2 2.8-.4 5.5-.4 8.4c0 53 43 96 96 96s96-43 96-96s-43-96-96-96c-2.8 0-5.6 .1-8.4 .4c5.3 9.3 8.4 20.1 8.4 31.6z"/></svg></span></template> <template id=fa-eye-slash><span class=fa-svg><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><!--! Font Awesome Free 6.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2022 Fonticons, Inc. --><path d="M38.8 5.1C28.4-3.1 13.3-1.2 5.1 9.2S-1.2 34.7 9.2 42.9l592 464c10.4 8.2 25.5 6.3 33.7-4.1s6.3-25.5-4.1-33.7L525.6 386.7c39.6-40.6 66.4-86.1 79.9-118.4c3.3-7.9 3.3-16.7 0-24.6c-14.9-35.7-46.2-87.7-93-131.1C465.5 68.8 400.8 32 320 32c-68.2 0-125 26.3-169.3 60.8L38.8 5.1zM223.1 149.5C248.6 126.2 282.7 112 320 112c79.5 0 144 64.5 144 144c0 24.9-6.3 48.3-17.4 68.7L408 294.5c5.2-11.8 8-24.8 8-38.5c0-53-43-96-96-96c-2.8 0-5.6 .1-8.4 .4c5.3 9.3 8.4 20.1 8.4 31.6c0 10.2-2.4 19.8-6.6 28.3l-90.3-70.8zm223.1 298L373 389.9c-16.4 6.5-34.3 10.1-53 10.1c-79.5 0-144-64.5-144-144c0-6.9 .5-13.6 1.4-20.2L83.1 161.5C60.3 191.2 44 220.8 34.5 243.7c-3.3 7.9-3.3 16.7 0 24.6c14.9 35.7 46.2 87.7 93 131.1C174.5 443.2 239.2 480 320 480c47.8 0 89.9-12.9 126.2-32.5z"/></svg></span></template> <template id=fa-copy><span class=fa-svg><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Free 6.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2022 Fonticons, Inc. --><path d="M502.6 70.63l-61.25-61.25C435.4 3.371 427.2 0 418.7 0H255.1c-35.35 0-64 28.66-64 64l.0195 256C192 355.4 220.7 384 256 384h192c35.2 0 64-28.8 64-64V93.25C512 84.77 508.6 76.63 502.6 70.63zM464 320c0 8.836-7.164 16-16 16H255.1c-8.838 0-16-7.164-16-16L239.1 64.13c0-8.836 7.164-16 16-16h128L384 96c0 17.67 14.33 32 32 32h47.1V320zM272 448c0 8.836-7.164 16-16 16H63.1c-8.838 0-16-7.164-16-16L47.98 192.1c0-8.836 7.164-16 16-16H160V128H63.99c-35.35 0-64 28.65-64 64l.0098 256C.002 483.3 28.66 512 64 512h192c35.2 0 64-28.8 64-64v-32h-47.1L272 448z"/></svg></span></template> <template id=fa-play><span class=fa-svg><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384 512"><!--! Font Awesome Free 6.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2022 Fonticons, Inc. --><path d="M73 39c-14.8-9.1-33.4-9.4-48.5-.9S0 62.6 0 80V432c0 17.4 9.4 33.4 24.5 41.9s33.7 8.1 48.5-.9L361 297c14.3-8.7 23-24.2 23-41s-8.7-32.2-23-41L73 39z"/></svg></span></template> <template id=fa-clock-rotate-left><span class=fa-svg><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Free 6.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2022 Fonticons, Inc. --><path d="M75 75L41 41C25.9 25.9 0 36.6 0 57.9V168c0 13.3 10.7 24 24 24H134.1c21.4 0 32.1-25.9 17-41l-30.8-30.8C155 85.5 203 64 256 64c106 0 192 86 192 192s-86 192-192 192c-40.8 0-78.6-12.7-109.7-34.4c-14.5-10.1-34.4-6.6-44.6 7.9s-6.6 34.4 7.9 44.6C151.2 495 201.7 512 256 512c141.4 0 256-114.6 256-256S397.4 0 256 0C185.3 0 121.3 28.7 75 75zm181 53c-13.3 0-24 10.7-24 24V256c0 6.4 2.5 12.5 7 17l72 72c9.4 9.4 24.6 9.4 33.9 0s9.4-24.6 0-33.9l-65-65V152c0-13.3-10.7-24-24-24z"/></svg></span></template>
<script> window.playground_copyable = true; </script>
<script src="elasticlunr-ef4e11c1.min.js"></script> <script src="mark-09e88c2c.min.js"></script> <script src="searcher-09f2665d.js"></script>
<script src="clipboard-1626706a.min.js"></script> <script src="highlight-abc7f01d.js"></script> <script src="book-609e4cb8.js"></script>
<!-- Custom JS scripts -->
</div> </body></html>