본문 바로가기

Algorithm/A. Intro & STL

16. Span

span은 C++20에 추가된 컨테이너로 연속된 수열의 형태로 저장되는 객체(정적 배열, std::array, std::vector, std::string 등; std::deque은 할당되는 메모리가 연속되지 않을 수 있기 때문에 제외된다)를 나타낼 수 있다. 헤더파일 <span>을 인클루드하면 span을 사용할 수 있다. span 클래스도 이 헤더파일에 정의되어 있다.

 

span의 선언은 일반적인 시퀀스 컨테이너와 비슷한데, 복사 생성자를 이용하여 선언할 때 원본이 span이 아닐 수도 있다.

#import<bits/stdc++.h>
using namespace std;
int main()
{
    int a[5] = {1, 2, 3, 4, 5};
    array<int,5> b({1, 2, 3, 4, 5});
    vector c({1, 2, 3, 4, 5});
    deque d({1, 2, 3, 4, 5});
    string e("abcde");
    
    span<int> s1;
    span s2(a);
    span s3(b);
    span s4(c);
    span s5(d); // Compilation Error
    span s6(e);
    span<char> s7(e);
    span s8(s1);
}

span은 $s1$과 같이 빈 컨테이너로 생성되거나 정적 배열, array, vector, string 또는 다른 span의 복사본이 될 수 있다. 이전 글에서 한 번도 언급한 적이 없지만, STL 객체를 선언할 때 원본이 존재하거나 초기화 목록을 사용하는 등 자료형을 결정할 수 있을 경우 자료형 명시를 생략할 수 있다. 위 코드에서 vector, deque와 일부 span을 선언할 때 자료형을 명시하지 않은 것을 알 수 있다. (단 array는 자료형 다음에 생략할 수 없는 인자가 더 있으므로 자료형을 결정할 수 있더라도 자료형 명시를 생략할 수 없다.) 원본이 string인 경우 $s6$ 또는 $s7$과 같은 방법으로 선언할 수 있다.

 

다음은 span의 멤버 함수이다:

s.front(); s의 첫 번째 원소를 참조한다.
s.back(); s의 마지막 원소를 참조한다.
s.size(); s에 들어 있는 원소의 개수를 반환한다.
s.size_bytes(); s의 바이트 크기를 반환한다.
s.empty(); s가 비었는지 확인한다.
s.begin(); s의 첫 원소를 가리키는 반복자를 반환한다.
s.end(); s의 끝을 가리키는 반복자를 반환한다.
s.rbegin(); s의 역 순차열의 첫 원소를 가리키는 반복자를 반환한다.
s.rend(); s의 역 순차열의 끝을 가리키는 반복자를 반환한다.
s.data(); s의 첫 원소를 가리키는 포인터를 반환한다.
s.first(n); s의 처음 n개의 원소로 구성된 span을 반환한다.
s.first<n>(); s의 처음 n개의 원소로 구성된 span을 반환한다.
s.last(n); s의 마지막 n개의 원소로 구성된 span을 반환한다.
s.last<n>(); s의 마지막 n개의 원소로 구성된 span을 반환한다.
s.subspan(i,n); s의 i~i+n-1번째 원소로 구성된 span을 반환한다.
s.subspan<i,n>(); s의 i~i+n-1번째 원소로 구성된 span을 반환한다.

함수의 매개변수로 span이 사용될 경우 포인터 값의 증가로 인해 데이터가 손상되는 것을 방지할 수 있다. 그밖에도 유용하게 쓰일 수 있지만 C++20 표준이라서 존재 자체가 거의 알려지지 않아 아직까지는 span이 사용되는 코드를 찾기는 쉽지 않다.

'Algorithm > A. Intro & STL' 카테고리의 다른 글

15. Valarray  (0) 2021.01.24
14. Bitset  (0) 2021.01.19
13. String  (0) 2021.01.17
12. Unordered Container  (0) 2021.01.15
11. Map & Multimap  (0) 2021.01.13