std::string_view
std::string_view란 무엇입니까?
std::string_view C++17 이후에 추가된 문자열 처리를 위한 매우 강력하고 효과적인 컨테이너입니다. 내부 구현은 다르지만 std::string_view작동 및 기능 std::span거의 비슷하다 std::span그만큼 std::vectorC 스타일 배열, std::array 다음과 같은 다양한 유형의 어레이를 효율적으로 처리하는 것으로 구성된 경우 std::string_view~이다 std::string, const char *, char () 와 같은 다양한 유형의 문자열을 보유하기 위해 존재합니다.
그동안 std::span(Modern 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
위의 코드는 3개의 입력을 받습니다. 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 여기에서도 다른 참조 유형과 마찬가지로 원본과 수명 주기에서 벗어나지 않도록 주의해야 합니다.