
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::weak_ptr (11) (1) | 2025.10.15 | 
|---|---|
| Modern C++ : std::shared_ptr (11, 17) (0) | 2025.10.14 | 
| Modern C++ : std::unique_ptr (11, 14) (0) | 2025.10.13 | 
| Modern C++ : std::format (20) (0) | 2025.10.12 | 
| 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 | 
 
										
									 
										
									 
										
									