raw_storage_iterator — std::raw_storage_iterator

raw_storage_iterator — std::raw_storage_iterator

std::raw_storage_iterator는 표준 알고리즘이 초기화되지 않은 메모리에 결과를 저장할 수 있게 해주는 출력 반복자(iterator)예요. C++17에서 deprecated, C++20에서 제거되었어요.

일반 알고리즘은 이미 초기화된 메모리에 할당하지만, raw_storage_iterator는 역참조된 반복자에 값을 쓸 때 그 위치에 T 객체를 복사 생성해요. 그래서 std::uninitialized_copy처럼 원시 저장 공간에 객체를 짓는 데 쓰였어요.

출처: cppreference

본문

std::raw_storage_iterator는 출력 반복자로, 알고리즘이 초기화되지 않은 메모리에 결과를 저장할 수 있게 해요.

template<class OutputIt, class T>
class raw_storage_iterator;

알고리즘이 역참조된 반복자에 T 타입 객체를 쓸 때마다, 그 객체는 반복자가 가리키는 초기화되지 않은 저장 공간에 복사 생성돼요. 템플릿 매개변수 OutputItOutputIterator 요구 사항을 만족하고, operator*operator&T* 타입 객체를 반환하는 객체를 반환하는 어떤 타입이든 돼요. 보통 T*OutputIt으로 쓰여요.

노트 (Note)

raw_storage_iterator는 주로 예외 안전하지 않은 동작 때문에 deprecated됐어요. std::uninitialized_copy와 달리, std::copy 같은 연산 중 예외를 안전하게 처리하지 않아서, 성공적으로 구성된 객체 수 추적과 예외 시 적절한 파괴가 없어 자원 누수가 생길 수 있어요.

예제 (Example)

#include <algorithm>
#include <iostream>
#include <memory>
#include <string>

int main()
{
    const std::string s[] = {"This", "is", "a", "test", "."};
    std::string* p = std::allocator<std::string>().allocate(5);

    std::copy(std::begin(s), std::end(s),
              std::raw_storage_iterator<std::string*, std::string>(p));

    for (std::string* i = p; i != p + 5; ++i)
    {
        std::cout << *i << '\n';
        i->~basic_string<char>();
    }
    std::allocator<std::string>().deallocate(p, 5);
}

출력:

This
is
a
test
.

allocator로 원시 메모리를 확보한 뒤, raw_storage_iterator로 그 메모리에 문자열을 복사 생성하고, 사용 후 소멸자를 직접 호출하고 deallocate하는 흐름이에요. 현대 코드에서는 std::uninitialized_copy를 쓰는 게 더 안전해요.

같이 보기

  • std::uninitialized_copy
  • std::allocator

더 알아보기 (Learn more)

cppreference