std::string_view
std::string_view란 무엇입니까?
std::string_view
C++17부터 추가된 문자열 처리를 위한 매우 강력하고 효율적인 컨테이너입니다.
내부 구현은 다르지만 std::string_view
작동 및 기능 std::span
거의 같다 std::span
이것 std::vector
C 스타일 배열, std::array
다음과 같이 다양한 유형을 효율적으로 처리할 수 있는 배열이 있다면 std::string_view
예 std::string
, const char *
, char ()
와 같은 다양한 유형의 문자열을 효율적으로 처리하기 위해 존재합니다.
동시에 std::span
(최신 C++) std::span이 궁금하다면 왜 사용해야 할까요?
원래 std::string_view
복사 구성이 없기 때문에 원래 문자열에 대한 강력한 참조가 있습니다.
하지만 이미 참조 유형이 있는데 왜 std::string_view
필요하세요?그 이유는 C++에서 std::string
다른 다양한 문자열 유형이 있기 때문입니다.
std::string, const char * 및 char()의 차이점
우선 C++에는 위에서 언급한 다양한 유형의 문자열이 있습니다.
std::string
사용하기 쉽지만 성능, 사용 편의성, 작업 환경 등에 따라 다릅니다.
std::string
때때로 (std::string
추상 클래스이기 때문에 메모리 관리 및 멤버 메소드 제공 측면에서 더 편리하지만, 일반적으로 const char *
등), 불행히도 성능이나 메모리 사용량 측면에서. std::string
, const char *
, char ()
그들은 모두 내부 구현이 약간 다릅니다.
예를 들어 std::string str1 = "script by";
선언하면 std::string
형제 str1
은 script by
문자열을 가리킬 것입니다.
이때 script by
크기에 따라 문자열이 힙 메모리 영역에 올라가는지 아니면 스택 메모리 영역에만 올라가는지에 따라 다릅니다.
.
동시에 const char * str2 = "nx006";
선언하면 nx006
호출된 문자열은 읽기 전용 저장소에 업로드됩니다.
그리고 str2
읽기 전용 메모리 영역의 문자열을 가리킵니다.
마침내 char() str3 = "CODE EDGE;"
선언하면 CODE EDGE
호출된 문자열은 스택 메모리 영역에 올라갑니다.
그리고 str3
이 문자열을 가리킬 것입니다.
기존 문자열 처리 문제
아래 코드를 살펴보겠습니다.
이 코드는 아나그램에 대한 해시를 생성합니다.
// anagram hash generator
std::string anagram_hash(const std::string& str)
{
std::map<char, int> alphabet_tables;
std::ranges::for_each(str, (&alphabet_tables)(const auto& c) {alphabet_tables(c)++; });
std::string hash = "";
for (const auto& (alphabet, number) : alphabet_tables) {
hash += alphabet;
hash += std::to_string(number);
}
return std::move(hash);
}
위 코드에서 파라미터 값의 타입으로 const std::string& str
다음과 같이 main 함수에서 문자열을 전달한다고 가정해 봅시다.
int main ()
{
std::string str1 = "AABBC";
const char * str2 = "AABBC";
char() str3 = "AABBC";
const auto hash1 = anagram_hash(str1);
const auto hash2 = anagram_hash(str2);
const auto hash3 = anagram_hash(str3);
std::cout << hash1 << '\n'
<< hash2 << '\n'
<< hash3 << '\n';
return 0;
}
결과:
A2B2C1
A2B2C1
A2B2C1
위의 코드에는 세 개의 입력이 필요합니다.
str1
, str2
, str3
나는 행동해야 한다.
그런데 자세한 동작 순서를 살펴보면 예상치 못한 동작이 발생한 것을 알 수 있습니다.
std::string str1
이를 위해 문제없이 작동합니다.
매개변수 유형은 참조 유형이므로 복사 생성자 없이 매개변수를 함수에 전달할 수 있습니다.
하지만 const char * str2
그리고 char() str3
문제는 통과되면 내부 std::string
다음 유형의 임시 개체를 만든 후 str2
그리고 str3
복제를 위한 복제 구조입니다.
그리고 복사된 메모리 str
그것을 가리킬 것입니다.
의도하지 않은 복사 생성자가 호출되어 성능이 저하되었습니다.
std::string_view 사용
이것을 해결하기 위해 우리는 std::string_view
매개변수 유형을 조정할 수 있습니다.
std::string anagram_hash(const std::string_view str)
{
std::map<char, int> alphabet_tables;
std::ranges::for_each(str, (&alphabet_tables)(const auto& c) {alphabet_tables(c)++; });
std::string hash = "";
for (const auto& (alphabet, number) : alphabet_tables) {
hash += alphabet;
hash += std::to_string(number);
}
return std::move(hash);
}
매개변수 유형 std::string&
존재하다 std::string_view
로 변경하면 str2
, str3
사용하는 경우에도 실수로 임시 개체의 복사본을 만들지 않고 함수 내에서 직접 원래 문자열을 참조할 수 있습니다.
std::string_view
매우 강력한 기능이며 구문을 이식하기 쉽기 때문에 적극적으로 사용할 수 있습니다.
std::string_view 사용 시 고려 사항
std::string_view
참조 유형입니다.
즉, 원본이 변경된 경우 std::string_view
또한 변경됩니다.
원래 메모리가 수명이 다해 파괴되면 std::string_view
또한 쓰레기 값을 가리킬 것입니다.
그러므로 std::string_view
또한 다른 참조형과 마찬가지로 기본형과 수명형을 벗어나지 않도록 주의해야 합니다.