std::basic_string<CharT,Traits,Allocator>::resize_and_overwrite
template< class Operation >
constexpr void resize_and_overwrite( size_type count, Operation op );
|
(C++23부터) | |
최대 count개의 문자를 포함하도록 문자열 크기를 조정하며, 사용자 제공 연산 op을 사용하여 불확정적인 내용을 수정하고 길이를 설정합니다. 이는 적절한 크기의 std::string을 초기화하는 비용을 피합니다(예: C API 호출로 채워질 char 배열로 사용하려는 경우).
이 함수는 다음 단계를 수행합니다:
count + 1개의 문자를 포함하는 연속 저장 공간을 얻고, 그 첫 번째k개의 문자를k의 첫 번째*this개의 문자와 동일하게 만듭니다. 여기서k은count과size()호출 전의 결과 중 더 작은 값입니다.resize_and_overwrite을 저장 공간의 첫 번째 문자를 가리키는 포인터라고 합시다.p동등성은- .
this->compare(0, k, p, k) == 0을 확인하는 것처럼 결정됩니다. [p + k,p + count]의 문자는 불확정적인 값을 가질 수 있습니다.
- .
std::move(op)(p, count)을 평가하고,r을 반환값이라고 합시다.*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) |