본문 바로가기
개발/C++ (98,03,11,14,17,20,23)

Modern C++ : std::span (20)

by snowoods 2025. 8. 23.

Modern C++

std::span

 

개요

std::span은 연속된 메모리 영역을 참조하는 가볍고 안전한 래퍼 클래스입니다. C++20에서 도입되었으며, 배열이나 컨테이너의 요소들에 대한 뷰를 제공합니다. 포인터와 크기 쌍을 추상화하여 더 안전하고 표현력 있는 코드를 작성할 수 있게 해줍니다.

 

C++ 버전별 주요 키워드 도입 시기

  • C++20: std::span 도입

 

내용 설명

std::span의 주요 특징:

  1. 가벼운 참조 타입: std::span은 데이터를 소유하지 않고, 기존 데이터에 대한 뷰만 제공합니다.
  2. 연속 메모리 컨테이너와 호환: std::vector, std::array, C-style 배열 등과 함께 사용할 수 있습니다.
  3. 런타임 크기 정보: 배열의 크기를 런타임에 알 수 있습니다.
  4. 범위 기반 for 루프 지원: 표준 컨테이너처럼 사용할 수 있습니다.
  5. 메모리 안전성: 범위 검사를 통해 안전한 접근을 제공합니다.

 

예제 코드

#include <array>
#include <cstdint>
#include <iostream>
#include <span>
#include <vector>

void print_span(std::span<std::int32_t> span)
{
    std::cout << "Span size: " << span.size() << '\n';
    for (const auto value : span)
    {
        std::cout << value << ' ';
    }
    std::cout << '\n';
}

int main()
{
    // std::vector와 함께 사용
    auto vec = std::vector<std::int32_t>{1, 2, 3};
    print_span(vec);

    // std::array와 함께 사용
    auto arr = std::array<std::int32_t, 3>{4, 5, 6};
    print_span(arr);

    // C-style 배열과 함께 사용
    int c_array[] = {7, 8, 9};
    print_span(c_array);

    // 부분 범위 접근
    std::span partial_span{vec.begin() + 1, 2};
    print_span(partial_span);

    return 0;
}

 

실행 결과

Span size: 3
1 2 3 
Span size: 3
4 5 6 
Span size: 3
7 8 9 
Span size: 2
2 3 

 

활용팁

  1. 함수 매개변수로 사용 시: std::vector<T>& 대신 std::span<T>을 사용하면 더 유연한 인터페이스를 제공할 수 있습니다.
  2. // Before void process(std::vector<int>& data); // After (more flexible) void process(std::span<int> data);
  3. 상수성 보존: const std::span<const T>를 사용하면 데이터를 수정할 수 없음을 명확히 할 수 있습니다.
  4. 부분 범위 접근: subspan() 메서드를 사용하여 부분 범위에 접근할 수 있습니다.
  5. auto sub = span.subspan(1, 2); // 인덱스 1부터 2개 요소
  6. 성능 고려사항: std::span은 가볍고 복사 비용이 저렴하지만, 참조 무효화에 주의해야 합니다.
  7. C++20 컴파일러 필요: std::span을 사용하려면 C++20 이상을 지원하는 컴파일러가 필요합니다.