----------------
title : C++ 레퍼런스 - basic_string
cat_title :  basic_string
ref_title : basic_string, std::basic_string
path : /C++ Reference/string
publish_date : 2020-07-17
----------------

##@ cpp-ref-start

#@ basic_string

```cpp-formatted
template <class CharT, class Traits = std::char_traits<CharT>,
          class Allocator = std::allocator<CharT> >
class basic_string;
```

아래는 C++ 17 에 추가된 정의

```cpp-formatted
namespace pmr {
template <class CharT, class Traits = std::char_traits<CharT>>
using basic_string =
  std::basic_string<CharT, Traits, std::polymorphic_allocator<CharT>>
}
```

`basic_string` 클래스 템플릿은, `char` 과 같은 **문자의 나열을 저장하고 또 수정하는 작업**을 도와줍니다. `basic_string` 은 문자 타입 자체를 추상화 시켜서 정의되어 있기 때문에, 사용하는 문자의 타입이 특정한 조건들만 만족하게 된다면, `basic_string` 의 기능을 전부 사용할 수 있습니다. 

따라서, `basic_string` 에 정의된 함수들은 **어떠한 문자 타입을 저장하느냐에 무관**하게 일반화된 방식으로 작동합니다. 덕분에, 1 바이트 문자든 2 바이트 문자든 어떤 크기의 문자를 사용하냐에 무관하게 라이브러리를 잘 사용할 수 있습니다.

**문자** 타입들 간의 연산 (비교, 이동 등등)은 `Traits` 를 통해 정의됩니다.\sidenote{예를 들어 대소문자 구분이 없는 string 을 만들 수 도 있습니다. Traits 에는 멤버 함수로 문자를 비교하는 함수가 있어야 하는데, 같은 대소문자 일 때도 true 를 반환하게 만들면 됩니다}

`Traits` 를 사용하는 이유는, `basic_string` 에 **어떤 문자가 저장되었냐** 에 관련한 로직과, **이 문자들을 어떻게 처리해야 할 것인가** 에 관련한 로직을 분리할 수 있기 때문입니다. 전자의 경우 `CharT` 자체에 의해 처리되고, 후자의 경우 `Traits` 에서 담당하게 됩니다.

`Traits` 는 `std::char_traits` 의 특수화 버전이어야만 합니다. 참고로 템플릿 인자인 `CharT` 와 `Traits::char_type` 는 반드시 같은 타입이어야만 합니다.

우리가 많이 쓰는 문자 타입인 `char` 이나 `wchar_t` 와 같은 타입들의 경우 이미 표준 라이브러리에서 친절하게 `Traits` 를 정의해주고 있기 때문에, 굳이 따로 걱정할 필요는 없습니다.

참고로 `C++ 11` 에 와서야 명시된 사실 중 하나로, `basic_string` 에서 저장된 문자열은 메모리에 반드시 순차적으로 존재해야만 합니다. 예를 들어서 `basic_string s` 의 경우 0 과 `s.size()` 의 n 이 오더라도 `&*(s.begin() + n) == &*s.begin() + n` 가 만족해야만 합니다. 마찬가지로, `s[0]` 의 주소값은, `CharT[]` 배열의 첫번째 원소의 주소값과 일치해야만 합니다.

`std::basic_string` 은 `AllocatorAwareContainer, SequenceContainer, ContiguousContainer` (이는 C++ 17 에 추가됨) 을 만족합니다.


자주 수행하는 문자 타입들에 대해 템플릿 특수화 버전들이 기본적으로 제공됩니다.

|타입|정의|
|----|----|
|`std::string`|`std::basic_string<char>`|
|`std::wstring`|`std::basic_string<wchar_t>`|
|`std::u16string`|`std::basic_string<char16_t>`|
|`std::u32string`|`std::basic_string<char32_t>`|

### 템플릿 인자들

* `CharT` -	문자의 타입. 흔히 사용하는 `std::string` 의 경우 `char` 이다.
* `Traits` - 개개 문자에 대한 작업을 정의하는 `traits` 클래스
* `Allocator` -	어떠한 방식으로 저장을 할 것인지 명시해주는 `Allocator` 타입

### 멤버 타입들

|멤버 타입|정의|
|-------|---|
|`traits_type`|`Traits` (템플릿 인자)|
|`value_type`|`CharT` (템플릿 인자)|
|`allocator_type`|`Allocator` (템플릿 인자)|
|`size_type`|`std::allocator_traits<Allocator>::size_type`|
|`difference_type`|`std::allocator_traits<Allocator>::difference_type`|
|`reference`|`value_type&`|
|`const_reference`|`const value_type&`|
|`pointer`|`std::allocator_traits<Allocator>::pointer`|
|`const_pointer`|`std::allocator_traits<Allocator>::const_pointer`|
|`iterator`|`RandomAccessIterator`|
|`const_iterator`|상수 `RandomAccessIterator`|
|`reverse_iterator`|`std::reverse_iterator<iterator>`|
|`const_reverse_iterator`|`std::reverse_iterator<const_iterator>`|

### 멤버 함수들

* [생성자](/237)
* 소멸자
* `operator=` : 문자열에 문자열을 대입한다.
* `assign$string` : 문자열에 문자를 대입한다.
* `get_allocator` : 사용된 할당자를 리턴한다.

#### 원소 접근 관련 함수들

* `at` : 특정 위치의 문자를 접근한다. (이 때 **범위를 체크함**)
* `operator[]` : 특정 위치의 문자에 접근한다.
* `front` : 첫 번째 문자에 접근한다.
* `back` : 마지막 문자에 접근한다.
* `data` : 문자열의 첫 번째 문자를 가리키는 포인터를 리턴한다.
* `c_str` : 문자열의 (수정 불가능한) C 스타일 문자열(NULL 로 끝남)을 리턴한다.
* `operator basic_string_view` : 전체 문자열의 수정 불가능한 `string_view` 를 리턴한다.

#### 반복자 관련

* `begin, cbegin` : 시작점을 가리키는 반복자를 리턴한다. (c 가 붙은 것의 경우 상수 반복자를 리턴한다)
* `end, cend` : 끝 점을 가리키는 반복자를 리턴한다.
* `rbegin, crbegin` : 시작점을 가리키는 역반복자를 리턴한다. (즉 실제로 문자열 맨 마지막 문자를 가리키고 있음
* `rend, crend`: 끝 점을 가리키는 역반복자를 리턴한다.

#### 문자열 크기/메모리 관련

* `empty` : 문자열이 비어있는지 확인한다. (비어있으면 true)
* `size, length` : 문자열의 길이를 리턴한다.
* `max_size` : 현재 시스템에서 보관할 수 있는 문자열의 최대 길이를 리턴한다.
* `reserve` : 문자열 공간을 미리 할당해놓는다.
* `capacity` : 현재 할당된 공간의 크기를 리턴한다.
* `shrink_to_fit` : 사용하지 않는 공간을 해제 한다.

#### 문자열 작업 관련

* `clear` : 문자열 전체를 깨끗하게 지워버린다.
* `insert` : 문자를 삽입한다.
* `erase` : 일부 문자열을 지운다.
* `push_back$string` : 맨 뒤에 문자를 추가한다.
* `pop_back` : 맨 뒤에 문자를 지운다.
* `append, operator+=` : 맨 뒤에 문자열을 붙인다.
* `compare` : 두 문자열을 비교한다.
* `starts_with` : 주어진 접두사(prefix) 로 문자열이 시작하는지 확인한다 (C++ 20 에 추가됨)
* `ends_with` : 주어진 접미사(suffix) 로 문자열이 끝나는지 확인한다 (C++ 20 에 추가됨)
* `replace` : 문자열의 일부를 치환한다.
* `substr` : 문자열의 일부를 리턴한다.
* `copy` : 문자들을 복사한다.
* `resize` : 저장된 문자들의 수를 바꾼다.
* `swap` : 문자열을 `swap` 한다.

#### 문자열 검색 관련

* `find` : 문자열을 검색한다.
* `rfind` : 문자열을 뒤에서 부터 검색한다.
* `find_first_of` : 전달된 문자열에 있는 문자가 가장 처음으로 나타나는 위치를 찾는다.
* `find_first_not_of` : 전달된 문자열에 없는 문자가 가장 처음으로 나타나는 위치를 찾는다.
* `find_last_of` : 전달된 문자열에 있는 문자가 가장 마지막으로 나타나는 위치를 찾는다.
* `find_last_not_of` : 전달된 문자열에 없는 문자가 가장 처음으로 나타나는 위치를 찾는다.

#### 상수

* `npos` : 사용 예에 따라 의미가 달라짐.

### 비-멤버 함수들

다음은 `basic_string` 의 멤버 함수는 아니지만, `basic_string` 과 밀접한 관련이 있는 함수들 입니다.

#### 입출력 관련

* `operator<<, operator>>` : 스트림에서 문자열 입출력을 수행한다.
* `getline` : 입출력 스트림에서 데이터를 읽어서 문자열에 저장한다.

#### 데이터 변환 관련

* `stoi, stol, stoll` : 문자열을 부호 있는 정수로 변환한다.
* `stoul, stoull` : 문자열을 부호 없는 정수로 변환한다.
* `stof, stod, stold` : 문자열을 부동 소수점 수로 변환한다.
* `to_string, to_wstring` : 정수나 부동 소수점 수를 `string` 이나 `wstring` 으로 변환한다.