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 를 사용하여 불확정적인 내용을 수정하고 길이를 설정합니다. 이는 C API 호출 등으로 채워질 char 배열로 사용하려는 std::string 을 적절한 크기로 초기화하는 비용을 피할 수 있습니다.
이 함수는 다음 단계를 수행합니다:
-
count
+
1
개의 문자를 포함하는 연속 저장 공간을 획득하고, 그 중 첫
k
개 문자를
*
this
의 첫
k
개 문자와 동일하게 설정합니다. 여기서
k
는
count
와
resize_and_overwrite
호출 전
size
(
)
결과 값 중 더 작은 값입니다.
저장 공간의 첫 번째 문자를 가리키는 포인터를
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 가 integer-like type 이 아닌 경우, 프로그램의 형식이 잘못되었습니다.
다음 조건 중 하나라도 충족되면, 동작은 정의되지 않습니다:
- std :: move ( op ) ( p, count ) 예외를 발생시킵니다.
- std :: move ( op ) ( p, count ) 이 p 또는 count 를 수정합니다.
-
r
이 범위
[ 0 ,count]내에 있지 않습니다. -
범위
[p,p + r)내의 모든 문자는 불확정된 값을 가집니다.
구현체는 불필요한 복사와 할당을 피하는 것이 권장되며, 예를 들어 p 를 호출 후 문자 저장을 위해 할당된 저장 공간의 시작 포인터로 설정하는 방식이 있습니다. 이는 * 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) |