Skip to content

std::mdspan (C++23) ​

In a nutshell ​

The multidimensional generalization of std::span: a multidimensional view over one contiguous block of memory. It does not own the data, its dimensions can be fixed at compile time or given at runtime, and indexing m[i, j] is zero-overhead.

Header file ​

#include <mdspan>

Core API Cheat Sheet ​

OperationSignatureDescription
Fixed extentsmdspan<T, extents<size_t, R, C>>Rows and columns known at compile time
Dynamic extentsmdspan<T, dextents<size_t, Rank>>Dimensions given at runtime
Indexingm[i, j]Multidimensional subscript (C++23 P2128) — note it is [], not ()
Row countm.extent(0)Size of dimension 0
Column countm.extent(1)Size of dimension 1
Total elementsm.size()Product of all dimensions
Rankm.rank()How many dimensions
Underlying pointerm.data_handle()Get the raw pointer
Layoutlayout_right (default) / layout_left / layout_strideRow-major / column-major / custom strides

Minimal Example ​

C++
// Standard: C++23
#include <mdspan>
#include <cstdio>

int main() {
    int data[2 * 3] = {1, 2, 3, 4, 5, 6};

    // Fixed extents: rows and columns known at compile time
    std::mdspan<int, std::extents<std::size_t, 2, 3>> m(data);
    std::printf("rows=%zu cols=%zu  m[0,0]=%d m[1,2]=%d\n",
                m.extent(0), m.extent(1), m[0, 0], m[1, 2]);

    // Dynamic extents: rows and columns given at runtime
    std::mdspan<int, std::dextents<std::size_t, 2>> dm(data, 2, 3);
    std::printf("dm[1,1]=%d size=%zu\n", dm[1, 1], dm.size());
}

Actual output (GCC 16.1.1, -std=c++23):

text
rows=2 cols=3  m[0,0]=1 m[1,2]=6
dm[1,1]=5 size=6

Embedded Suitability: Medium ​

  • A zero-ownership view with no allocation: its size is just a pointer plus the extents (a few dozen bytes), which suits memory-constrained settings
  • Multidimensional sensor data (images, matrices, ADC samples) can be passed around zero-copy, replacing hand-computed row*cols+col indexing
  • The compile-time fixed-extent (extents) version can be optimized so thoroughly that everything lives in registers, with no runtime overhead
  • Note that the multi-argument operator[] only exists as of C++23; the old operator() spelling found in older references no longer compiles on GCC 16

Compiler Support ​

GCCClangMSVC
141719.36

See Also ​


Part of the content is referenced from cppreference.com and is licensed under CC-BY-SA 4.0

pdf-latest-4-g85128cc · 85128cc · 2026-10-05