C++ 템플릿과 std::span을 활용한 컨테이너 순회
개요
C++ 템플릿은 다양한 데이터 타입에 대해 동작하는 일반화된 코드를 작성할 수 있게 해주는 강력한 기능입니다. std::span
은 C++20에서 도입된 뷰(view) 타입으로, 연속된 메모리 영역을 안전하고 편리하게 다룰 수 있게 해줍니다. 이 두 기능을 조합하면 다양한 컨테이너 타입을 일관된 방식으로 처리할 수 있는 유연한 코드를 작성할 수 있습니다.
C++ 버전별 주요 키워드 도입 시기
- C++98/03: 기본 템플릿 지원 시작
- C++11:
auto
, 범위 기반 for 루프,std::array
도입 - C++14: 일반화된 람다 캡처, 변수 템플릿
- C++17: 클래스 템플릿 인수 추론(CTAD),
std::string_view
- C++20:
std::span
, 개념(Concepts), 제약 조건 템플릿
내용 설명
템플릿 기본 구문
template <typename T>
void function_name(T parameter) {
// 함수 본문
}
template <typename T>
: T라는 이름의 템플릿 매개변수를 선언T
는 컴파일 시점에 실제 타입으로 대체됨typename
대신class
키워드도 사용 가능 (의미상 동일)
std::span
- 연속된 메모리 시퀀스의 뷰를 제공하는 클래스 템플릿
- 컨테이너의 데이터를 복사하지 않고 참조만 유지 (소유권 없음)
std::vector
, 배열,std::array
등 연속 메모리 컨테이너와 호환- 크기 정보를 함께 전달하므로 배열 붕괴(decay) 문제 방지
예제 코드
#include <array>
#include <cstdint>
#include <iostream>
#include <span>
#include <vector>
// 템플릿 함수: 모든 연속 컨테이너를 받아 요소 출력
template <typename T>
void print_container(std::span<T> span)
{
std::cout << "Container elements (size: " << span.size() << "):\n";
for (const auto& val : span)
{
std::cout << val << ' ';
}
std::cout << "\n\n";
}
int main()
{
// 다양한 타입의 컨테이너들
auto my_vec = std::vector<std::int32_t>{1, 2, 3, 4, 5};
auto my_arr = std::array<std::uint16_t, 5U>{1, 2, 3, 4, 5};
std::uint64_t my_c_arr[] = {1, 2, 3, 4, 5};
// 템플릿 함수 호출 (타입 명시적 지정)
print_container<std::int32_t>(my_vec);
print_container<std::uint16_t>(my_arr);
print_container<std::uint64_t>(my_c_arr);
// C++17부터는 템플릿 인자 추론으로 타입 생략 가능
print_container<int>({my_vec.data(), 3}); // 처음 3개 요소만 출력
return 0;
}
실행 결과
Container elements (size: 5):
1 2 3 4 5
Container elements (size: 5):
1 2 3 4 5
Container elements (size: 5):
1 2 3 4 5
Container elements (size: 3):
1 2 3
활용팁
- 성능 최적화:
std::span
은 데이터를 복사하지 않으므로 대용량 데이터 처리 시 성능 이점이 있습니다. - 타입 안전성: C 스타일 배열보다 안전하며, 크기 정보를 함께 전달할 수 있습니다.
- 제네릭 프로그래밍: 다양한 컨테이너 타입을 하나의 템플릿 함수로 처리할 수 있습니다.
- 인터페이스 단순화: 함수 매개변수로 포인터와 크기를 따로 전달할 필요가 없어집니다.
- 주의사항:
std::span
은 참조만 유지하므로, 원본 데이터의 수명이span
보다 길어야 합니다. - C++20 이상 필요: 프로젝트에서 C++20 이상을 지원해야 사용 가능합니다.
- 컴파일러 지원: 최신 버전의 GCC(10+), Clang(10+), MSVC(2019 16.7+)에서 완전히 지원됩니다.
'개발 > C++ (98,03,11,14,17,20,23)' 카테고리의 다른 글
Modern C++ : std::vector, emplace_back vs push_back (98, 11, 17) (0) | 2025.08.22 |
---|---|
Modern C++ : std::vector (98, 11, 14, 17, 20) (0) | 2025.08.21 |
Modern C++ : perfect forwarding (11) (1) | 2025.08.19 |
Modern C++ : rvalue reference summary (11) (2) | 2025.08.18 |
Modern C++ : lvalue, rvalue, value category (98, 11) (2) | 2025.08.17 |
Modern C++ : rvalue reference (98, 11) (1) | 2025.08.16 |
Modern C++ : lvalue rvalue reference (98, 11) (2) | 2025.08.15 |
Modern C++ : dynamic heap memory allocation (98, 11, 14) (1) | 2025.08.14 |