std::ranges
개요
std::ranges
는 C++20에 도입된 주요 기능으로, 컬렉션(컨테이너)을 다루는 방식을 혁신적으로 개선합니다. 기존의 반복자(iterator) 기반의 알고리즘을 파이프라이닝(pipelining) 가능한 '뷰(view)'와 '어댑터(adapter)'를 통해 더 직관적이고 가독성 높게 사용할 수 있도록 합니다. 이를 통해 복잡한 데이터 처리 로직을 간결하게 표현할 수 있습니다.
C++ 버전별 주요 키워드 도입 시기
- C++20 :
std::ranges
,std::views
,concepts
와 함께 도입되었습니다.
내용 설명
std::ranges
라이브러리는 크게 세 가지 요소로 구성됩니다.
- Ranges (범위): 반복 가능한 요소의 시퀀스를 나타내는 개념입니다.
std::vector
,std::list
와 같은 컨테이너는 범위가 될 수 있습니다. - Views (뷰): 범위에 대한 경량(lightweight) 어댑터입니다. 뷰는 데이터를 소유하지 않고, 원본 데이터를 변환하거나 필터링하는 방법을 정의합니다. 뷰는 조합(composable)이 가능하여 여러 변환을 파이프라인처럼 연결할 수 있습니다.
std::views
네임스페이스에는filter
,transform
,take
,drop
등 다양한 뷰 어댑터가 포함되어 있습니다. - Algorithms (알고리즘): 기존의
<algorithm>
헤더에 있던 알고리즘들이std::ranges
버전으로 오버로드되었습니다. 이 알고리즘들은 반복자 쌍 대신 범위를 직접 인자로 받을 수 있어 코드가 간결해집니다.
std::ranges
의 가장 큰 장점 중 하나는 파이프라인 연산자 |
를 사용하여 뷰를 연결할 수 있다는 점입니다. 이를 통해 데이터 처리 흐름을 왼쪽에서 오른쪽으로 자연스럽게 읽을 수 있습니다.
예를 들어, numbers | std::views::filter(...) | std::views::transform(...)
와 같은 코드는 numbers
컬렉션에 대해 필터링을 적용한 후, 그 결과에 변환을 적용하는 과정을 명확하게 보여줍니다.
예제 코드
#include <algorithm>
#include <iostream>
#include <ranges>
#include <string_view>
#include <vector>
auto print = [](auto const &view) {
std::cout << "{ ";
for (const auto element : view)
{
std::cout << element << ' ';
}
std::cout << "} ";
};
int main()
{
// Drop, Take, Transform, Filter
auto numbers1 = std::vector<int>{1, 2, 3, 4, 5, 6};
auto results1 = std::views::reverse(numbers1) | std::views::drop(2) |
std::views::take(3) |
std::views::transform([](const auto n) { return n * 2; }) |
std::views::filter([](const auto n) { return n % 2 == 0; });
for (auto v : numbers1)
std::cout << v << " ";
std::cout << std::endl;
for (auto v : results1)
std::cout << v << " ";
std::cout << std::endl;
// Filter, Transform
auto numbers2 = std::vector<int>{1, 2, 3, 4, 5, 6};
auto results2 = numbers2 |
std::views::filter([](int n) { return n % 2 == 0; }) |
std::views::transform([](int n) { return n * 2; });
for (auto v : results2)
std::cout << v << " ";
std::cout << std::endl;
// Split
constexpr auto hello = std::string_view{"Hello C++ 20 !"};
auto res = hello | std::ranges::views::split(' ');
std::cout << "substrings: ";
std::ranges::for_each(res, print);
return 0;
}
실행 결과
1 2 3 4 5 6
8 6 4
4 8 12
substrings: { H e l l o } { C + + } { 2 0 } { ! }
활용팁
- 지연 평가(Lazy Evaluation):
std::ranges
의 뷰는 지연 평가됩니다. 즉, 실제 요소가 필요할 때까지 계산이 수행되지 않습니다. 이는 불필요한 계산을 줄여 성능을 향상시킬 수 있습니다. - 가독성 향상: 복잡한 STL 알고리즘 호출 체인을 파이프라인으로 대체하여 코드의 가독성과 유지보수성을 크게 향상시킬 수 있습니다.
- 무한 시퀀스:
std::views::iota
와 같은 뷰를 사용하면 무한한 데이터 시퀀스를 표현하고 필요한 만큼만 처리할 수 있습니다. - 조합성: 다양한 뷰를 조합하여 복잡한 데이터 처리 파이프라인을 쉽게 구축할 수 있습니다. 예를 들어, 필터링, 변환, 정렬, 일부 요소 선택 등의 작업을 하나의 표현식으로 연결할 수 있습니다.
'개발 > C++ (98,03,11,14,17,20,23)' 카테고리의 다른 글
Modern C++ : std::Attributes (11, 14, 17, 20) (0) | 2025.10.10 |
---|---|
Modern C++ : std::any (17) (0) | 2025.09.30 |
Modern C++ : std::variant (17) (0) | 2025.09.29 |
Modern C++ : std::optional (17) (0) | 2025.09.28 |
Modern C++ : Type Traits 2 (11, 14, 17, 20) (0) | 2025.09.27 |
Modern C++ : Variadic Templates and Fold Expressions (11, 17) (0) | 2025.09.26 |
Modern C++ : std::concepts (20) (0) | 2025.09.25 |
Modern C++ : Type Traits 1 (11, 14, 17, 20) (0) | 2025.09.24 |