Skip to content
  • Arrays, std::array & std::span · C++

Arrays, std::array & std::span

LearnViaNotes @learnvianotes· 3 min read

C arrays are fixed-size blocks that decay to pointers. std::array is the same thing with value semantics and a size; std::span is a non-owning view over any contiguous sequence.

C-style arrays

C++
#include <iostream>
#include <iterator>

int main() {
    int a[5] = {1, 2, 3};                 // remaining elements are zero-initialised
    int b[] = {4, 5, 6};                  // size deduced: 3
    int grid[2][3] = {{1, 2, 3}, {4, 5, 6}};

    std::cout << a[3] << ' ' << std::size(b) << ' ' << sizeof(a) / sizeof(a[0]) << '\n';
    std::cout << grid[1][2] << '\n';
    for (int x : b) std::cout << x;       // range-for works: the size is part of the type
    std::cout << '\n';
}
Output
0 3 5
6
456

std::array<T, N>

C++
#include <algorithm>
#include <array>
#include <iostream>

std::array<int, 3> doubled(std::array<int, 3> arr) {   // passed & returned by value — just works
    for (int& x : arr) x *= 2;
    return arr;
}

int main() {
    std::array<int, 5> a{5, 3, 9, 1, 7};
    std::sort(a.begin(), a.end());
    std::cout << a.size() << ' ' << a.front() << ' ' << a.back() << '\n';

    auto copy = a;                 // arrays are copyable
    copy[0] = 100;
    std::cout << a[0] << ' ' << (a == copy) << '\n';

    auto d = doubled({1, 2, 3});
    std::cout << d[2] << '\n';

    try {
        std::cout << a.at(10) << '\n';      // bounds-checked access
    } catch (const std::out_of_range& e) {
        std::cout << "out_of_range\n";
    }
}
Output
5 1 9
1 0
6
out_of_range
C array T[N]std::array<T,N>std::vector<T>
SizeFixed, compile timeFixed, compile timeDynamic
StorageInline (stack/static)Inline (stack/static)Heap
Knows its sizeOnly in scope of declaration.size().size()
Copy / compare with = ==NoYesYes
Decays to pointerYesNo (.data() if needed)No
Bounds checkNever.at().at()

std::span (C++20)

A span<T> is a pointer + length — a cheap view. Write one function that accepts a C array, std::array or std::vector:

C++
#include <array>
#include <iostream>
#include <span>
#include <vector>

int sum(std::span<const int> xs) {
    int s = 0;
    for (int x : xs) s += x;
    return s;
}

int main() {
    int raw[] = {1, 2, 3};
    std::array<int, 2> arr{10, 20};
    std::vector<int> vec{100, 200, 300, 400};
    std::cout << sum(raw) << ' ' << sum(arr) << ' ' << sum(vec) << '\n';
    std::span<int> part(vec.data() + 1, 2);        // a sub-range
    part[0] = 0;                                    // writes through to vec
    std::cout << sum(part) << ' ' << vec[1] << ' ' << sum(std::span(vec).first(2)) << '\n';
}
Output
6 30 1000
300 0 100

Why can't you get the size of an array inside a function that receives it?

Free for students and teachers

Write notes like this one

Cards for every idea, quizzes and flashcards, read aloud — on the web and your phone.

Something wrong with this note? Open it to report