먼저 알아야 할 개념 : 문자열 리터럴

 

overview

std::string_view 클래스는  "문자열에 대한 비소유 참조"  이다
문자열에 대한 "상수 참조" 또는 "읽기 전용 참조" 라고 할 수도 있지만, 
const std::string& 로 오해할 수 있기 때문에 이렇게 정의한다.

실질적인 기능을 제공하는 것은 std::basic_string_view라는 템플릿이다.

 std::string_view는 미리 정의된 std::basic_string_view<char>의 별칭일 뿐..(std::basic_string 을 std::string으로 쓰는것과 유사)

 

 

 

std::string

  • C Style 문자열 표현
    • 문자열의 마지막에 널문자(\0)를 붙여서 끝남을 표시함
  • std::string
    • <string> 헤더에 정의
    • 비교연산자
      • 연산자 오버로딩 
        • == , != , < 와 같은 연산자를 사용할 수 있음
      • compare 메소드 사용가능
      • cpp 20부터는 3-way 비교연산자로 수행 가능 
    • 메모리 관리 
      • string클래스에서 알아서 해줌 -> 메모리 오버런 걱정 없음
        • 자세히 보자면... 
          • string을 할당하거나, 크기 변경 코드가 여기저기 있더라도 메모리 누수가 발생하지 x
            • string객체는 모두 스택변수이기 때문에 생성된 스코프를 벗어나면 알아서 소멸자에서 정리
          • 연산자를 원하는 방식으로 동작할 수 있음
    • c_str() 메소드를 사용하면 C언어에서 호환되는 const char 포인터를 얻을 수 있음
      • but 리턴된 const포인터는 string에 대한 메모리를 재할당하거나 해당 객체를 제거하면 유효치 않음
      • 현재 string에 담긴 내용을 정확히 사용하려면 이 메소드를 호출한 직후에 리턴된 포인터를 바로 활용
      • 함수 안에서 생성된 스택 기반의 string 객체에 대해서 c_str()을 호출한 결과를 절대로 리턴값으로 전달하면 안된다.

 

 

 std::string_view

만약 읽기 전용 문자열을 매개변수로 받는 함수를 작성한다면, 해당 문자열에 대한 타입은 어떻게 정하겠는가?

  • const char* 로 지정한다면, std::string을 사용하는 클라이언트에서 c_str()나 data()를 사용하여 string을 const char*로 변환해서 호출해야 하는 단점이 있다.
  •  const std::string& 으로 지정한다면, 항상 std::string만 사용해야한다.
    • 예를 들어 문자열 리터럴을 전달하면 컴파일러는 그 문자열 리터럴의 복사본이 담긴 string 객체를 생성하여 함수로 전달하기 때문에 오버헤드가 발생된다

즉, 이 클래스의 주된 용도는 const string&을 대신하는 것 이다!

 

만약 아래와 같은 함수가 있다고 치자.

void A(const string& str)
{
	cout<<str;
}
void B(const char* str)
{
	cout<<str;
}

 

위 A() B() 모두 단순히 문자열을 입력받아 출력하는 함수이다

 

std::string str = "hello";

A("hi");
B(str.c_str());

하지만 이렇게 호출한다면, 둘 다 위에서 말한 문제가 발생한다.

  • A("hi")의 경우에는 결국 const char*로 간주되며, string(const char*) 생성자가 실행되어 메모리 할당과 문자열 자료 복사가 발생한다.
  • B(str.c_str())의 경우에는 string을 사용하기 때문에 변환해서 매개변수에 넣어주어야한다.
void C(const string_view& str)
{
	cout<<str;
}

이렇게 선언한다면 두가지 다 필요 없지롱!

 

또 주목할 점은 아래의 몇가지가 있다

  • 연산자 오버로딩 지원
  • c_str()함수가 없다
  • data()가 돌려주는 것이 종료 문자열이 아니다
  • string_view만의 인터페이스가 추가 되었다
    • remove_prefix  및 remove_suffix
  •  cpp 17에서 string_view를 위한 문자열 리터럴을 추가했다!
    • "hi"sv 처럼 끝에 접미사 sv가 붙은 문자열 리터럴은 상수 string_view객체가 된다

 

 

참고 사항

https://en.cppreference.com/w/cpp/string/basic_string_view

 

std::basic_string_view - cppreference.com

template<     class CharT,     class Traits = std::char_traits > class basic_string_view; (since C++17) The class template basic_string_view describes an object that can refer to a constant contiguous sequence of char-like objects with the first elemen

en.cppreference.com

https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3921.html

 

string_view: a non-owning reference to a string, revision 7

Acknowledgements I'd like to thank Marshall Clow, Olaf van der Spek, the Boost and std-proposals mailing lists, Chandler Carruth, Beman Dawes, Alisdair Meredith, and especially Daniel Krügler for help, advice, and wording in this paper.

www.open-std.org

https://junstar92.tistory.com/305

 

[C++] string과 string_view

References Professional C++ https://en.cppreference.com/w/ Contents C-Style Strings String Literals Raw String Literals C++ std::string 클래스 std::string_view 클래스 Nonstandard Strings C 언어에서는 단순히 널(NULL)로 끝나는 문자 배

junstar92.tistory.com

 

복사했습니다!