오보에블로그

[C++20] Range 본문

C++ & C#/Modern C++

[C++20] Range

(OBO) 2022. 1. 31. 21:23
728x90

Range 라이브러리

  • 기존의 열거형 자료구조에 범위 관련 알고리즘을 추가한 라이브러리. (C# LINQ 와 비슷)
  • range : 순회 할 수 있는 아이템 집합를 일컫는다. (ex STL Container)
    • begin() , end() 가 가능해야함. iterator의 상위 호환 느낌인가
  • view : 아래에서 좀더 자세히 기술
  • range adoptor :
  • | : range adoptor 오브젝트를 연결(파이프)

View

  • 독스도 찾아보고, 블로그도 찾아보았지만, 의미가 잘 와닿지 않아 좀더 찾아보았다. 참고
  • a view is a range that is semiregular and has constant time copy/move/assignment
  • 뷰는 range의 is-a 관계라고 생각하면 된다. 집합의 크기에 상관없이 copy/move/assignment시에 상수 시간 복잡도를 갖는다.
  • 모든 열거형 자료구조는 view로 변환이 가능하다.
  • 다음과 같이 코드를 작성해서 뷰를 생성할 수 있다.
  • 파이프 연산자(|) 를 통해 뷰끼리 연결해서 연산이 가능하다.
vector<int> v1 = { 1,2,3,4,5 };
auto view{ std::views::all(v1) }; // 해당 range의 모든 원소를 포함하는 뷰 생성


예시

  • Range 라이브러리에서 제공하는 유용한 메소드를 이용해서 예시를 작성해본다.
  • 여담으로, view::메소드명 은 사실 ranges::view::메소드명 이지만, 내부에서 이름공간을 지정해줘서, 바로 view절로 작성 가능하다.

예시 - 1

  • view:filter( Pred&& pred ) : 해당 조건을 true로 만족하는 원소로 필터링한 뷰
  • view::transform( F&& fun ) : 각각의 원소를 fun에 적용시킨 뷰
  • 주의 : 파이프 연산을 사용할때 첫 번째 변수는 왼값(l-value)여야한다.
// 벡터 v1에서 짝수 인 원소들로만 필터링하고, 남은 원소들에 2를 곱한다.
vector<int> v1 = { 1,2,3,4,5,6,7,8,9,10 };
auto results = v1 | std::views::filter([](int n) {return n % 2 == 0; }) 
                  | std::views::transform([](int n) {return n * 2; });

예시 -2

  • view::iota( W&& value, Bound&& bound ) : value로부터 반복적으로 bound까지 증가시킨 시퀀스 뷰
  • view::take( DifferenceType&& count ) : 뷰에서 처음부터 N개의 원소를 취해 뷰 생성
// 1. 0 ~ 99까지의 원소를 가진 뷰 생성
// 2. 소수인 원소로만 필터링
// 3. 앞 원소 다섯개만 취한다.
std::vector<int> v3;

for (int n : std::views::iota(0, 100) |
             std::views::filter(isPrime) |
             std::views::take(5))
{
    v3.push_back(n);
}
728x90

'C++ & C# > Modern C++' 카테고리의 다른 글

[STL] STL 알고리즘 정리  (0) 2022.01.31
[C++20] Concepts library  (0) 2022.01.31
[C++20] Concept  (0) 2022.01.30