Namespaces
Variants

std::basic_string<CharT,Traits,Allocator>::resize_and_overwrite

cppreference.net에서
 
 
 
std::basic_string
 
template< class Operation >
constexpr void resize_and_overwrite( size_type count, Operation op );
(C++23부터)

최대 count개의 문자를 포함하도록 문자열 크기를 조정하며, 사용자 제공 연산 op을 사용하여 불확정적인 내용을 수정하고 길이를 설정합니다. 이는 적절한 크기의 std::string을 초기화하는 비용을 피합니다(예: C API 호출로 채워질 char 배열로 사용하려는 경우).

이 함수는 다음 단계를 수행합니다:

  1. count + 1개의 문자를 포함하는 연속 저장 공간을 얻고, 그 첫 번째 k개의 문자를 k의 첫 번째 *this개의 문자와 동일하게 만듭니다. 여기서 k은 count과 size() 호출 전의 결과 중 더 작은 값입니다. resize_and_overwrite을 저장 공간의 첫 번째 문자를 가리키는 포인터라고 합시다. p동등성은
    • .this->compare(0, k, p, k) == 0을 확인하는 것처럼 결정됩니다.
    • [p + k, p + count]의 문자는 불확정적인 값을 가질 수 있습니다.
  2. std::move(op)(p, count)을 평가하고, r을 반환값이라고 합시다.
  3. *this의 내용을 [p, p + r)(으)로 대체합니다(*this의 길이를 r(으)로 설정합니다). 범위 [p, p + count]에 대한 모든 포인터와 참조를 무효화합니다.

r이 정수형이 아닌 경우, 프로그램의 형식이 잘못되었습니다.

다음 조건 중 하나라도 충족되면, 동작은 정의되지 않습니다:

  • std::move(op)(p, count)이 예외를 던집니다.
  • std::move(op)(p, count)p 또는 count을 수정합니다.
  • r이 범위 [0, count]에 있지 않습니다.
  • 범위 [p, p + r)의 문자에 불확정적인 값이 있습니다.

구현은 불필요한 복사와 할당을 피하기 위해, 예를 들어 호출 후 p가 *this을 위해 할당된 문자의 저장 공간 시작을 가리키는 포인터와 같게 만드는 것이 권장됩니다. 이는 만약 *this이 count보다 작거나 같으면 capacity()의 기존 저장 공간과 동일할 수 있습니다.

매개변수

count - 문자열의 최대 가능한 새 크기
op - 문자열의 새 내용을 설정하는 데 사용되는 함수 객체

예외

std::length_error 이 count > max_size ( ) 인 경우. 해당 Allocator 에 의해 발생하는 모든 예외.

예외가 std :: move ( op ) ( p, count ) 에서 발생하면, 동작은 정의되지 않습니다. 그렇지 않고 예외가 발생하면, 이 함수는 아무런 효과도 가지지 않습니다.

참고 사항

resize_and_overwrite 는 재할당 발생 여부와 관계없이 * this 에 대한 모든 반복자, 포인터, 참조를 무효화합니다. 구현체는 resize_and_overwrite 호출 후 문자열 내용이 별칭화되지 않는다고 가정할 수 있습니다.

기능 테스트 매크로 값 표준 기능
__cpp_lib_string_resize_and_overwrite 202110L (C++23) std::basic_string::resize_and_overwrite

예제

예제 테스트 링크: compiler explorer .

#include <algorithm>
#include <cassert>
#include <cstddef>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <string>
#include <string_view>
static_assert(__cpp_lib_string_resize_and_overwrite);
constexpr std::string_view fruits[]{"사과", "바나나", "코코넛", "날짜", "엘더베리"};
int main()
{
    // 간단한 경우, fruits[0]만 추가합니다. 문자열 크기가 증가합니다.
    std::string s{"음식: "};
    s.resize_and_overwrite(16, [sz = s.size()](char* buf, std::size_t buf_size) noexcept
    {
        const auto to_copy = std::min(buf_size - sz, fruits[0].size());
        std::memcpy(buf + sz, fruits[0].data(), to_copy);
        return sz + to_copy;
    });
    std::cout << "1. " << std::quoted(s) << '\n';
    // 크기 축소 케이스. 사용자의 람다는 항상 호출됩니다.
    s.resize_and_overwrite(10, [](char* buf, int n) noexcept
    {
        return std::find(buf, buf + n, ':') - buf;
    });
    std::cout << "2. " << std::quoted(s) << '\n';
    std::cout << "3. 버퍼가 가득 찰 때까지 데이터를 복사합니다. 데이터와 크기를 출력합니다.\n";
    std::string food{"음식:"};
    const auto resize_to{27};
    std::cout << "초기 food.size: " << food.size()
              << ", food.capacity: " << food.capacity()
              << ", resize_to: " << resize_to
              << ", food: " << std::quoted(food) << '\n';
    food.resize_and_overwrite
    (
        resize_to,
        [food_size = food.size()](char* p, std::size_t n) noexcept -> std::size_t
        {
            // p[0]..p[n]은 할당 가능한 범위입니다
            // p[0]..p[min(n, food_size) - 1]은 읽기 가능한 범위입니다
            // (내용은 원본 문자열과 처음에 동일함)
            // 디버그 출력:
            std::cout << "In Operation(); n: " << n << '\n';
            // 충분한 공간이 있는 동안 과일들을 버퍼 p로 복사합니다.
            char* first = p + food_size;
            for (char* const end = p + n; const std::string_view fruit : fruits)
            {
                char* last = first + fruit.size() + 1;
                if (last > end)
                    break;
                *first++ = ' ';
                std::ranges::copy(fruit, first);
                first = last;
            }
            const auto final_size{static_cast<std::size_t>(first - p)};
            // 디버그 출력:
            std::cout << "In Operation(); final_size: " << final_size << '\n';
            assert(final_size <= n);
            return final_size; // 반환 값은 실제 새로운 길이입니다
                               // 문자열의 길이, 0..n 범위 내에 있어야 함
        }
    );
    std::cout << "마지막으로, food.size: " << food.size()
              << ", food.capacity: " << food.capacity()
              << ", food: " << std::quoted(food) << '\n';
}

가능한 출력:

1. "Food: apple"
2. "Food"
3. 버퍼가 가득 찰 때까지 데이터를 복사합니다. 데이터와 크기를 출력합니다.
Initially, food.size: 5, food.capacity: 15, resize_to: 27, food: "Food:"
In Operation(); n: 27
In Operation(); final_size: 26
Finally, food.size: 26, food.capacity: 30, food: "Food: apple banana coconut"

참고 항목

저장된 문자 수를 변경합니다
(public member function)