string_char_traits

string_char_traits (문자 특성)

char_traits 클래스는 주어진 문자 타입에 대한 기본 문자 및 문자열 연산을 추상화하는 특성(traits) 클래스 템플릿이에요. 정의된 연산 집합 덕분에 일반적인 알고리즘은 거의 항상 이 클래스를 기반으로 구현될 수 있어요. 따라서 맞춤형 char_traits 클래스를 제공하기만 하면 거의 모든 문자 또는 문자열 타입에 그런 알고리즘을 사용할 수 있답니다.

char_traits 클래스 템플릿은 명시적 인스턴스화의 기반으로 사용돼요. 사용자는 임의의 사용자 정의 문자 타입에 대해 특수화를 제공할 수 있어요. 표준 문자 타입에 대해서는 여러 명시적 특수화가 제공되며(아래 참조), 다른 특수화는 CharTraits 요구 사항을 충족할 필요는 없어요.

출처: cppreference

본문

특수화

표준 라이브러리는 다음과 같은 표준 특수화를 제공해요.

헤더에 정의됨
std :: char_traits < char >
std :: char_traits < wchar_t >
std :: char_traits < char8_t > (C++20)
std :: char_traits < char16_t > (C++11)
std :: char_traits < char32_t > (C++11)

이 모든 특수화는 CharTraits 요구 사항을 충족해요.

멤버 타입

표준 특수화는 CharTraits가 요구하는 다음 멤버 타입을 정의해요.

CharT 멤버 타입
char_type int_type
char char
wchar_t wchar_t
char8_t char8_t
char16_t char16_t
char32_t char32_t

그에 더해, 표준 특수화는 멤버 타입 comparison_categorystd::strong_ordering으로도 정의해요. (C++20부터)

멤버 함수

표준 특수화는 CharTraits가 요구하는 다음 정적 멤버 함수를 정의해요.

함수 설명
assign [static] 문자를 할당해요 (공용 정적 멤버 함수)
eq lt [static] 두 문자를 비교해요 (공용 정적 멤버 함수)
move [static] 한 문자 시퀀스를 다른 곳으로 이동해요 (공용 정적 멤버 함수)
copy [static] 문자 시퀀스를 복사해요 (공용 정적 멤버 함수)
compare [static] 두 문자 시퀀스를 사전순으로 비교해요 (공용 정적 멤버 함수)
length [static] 문자 시퀀스의 길이를 반환해요 (공용 정적 멤버 함수)
find [static] 문자 시퀀스에서 문자를 찾아요 (공용 정적 멤버 함수)
to_char_type [static] int_type을 동등한 char_type으로 변환해요 (공용 정적 멤버 함수)
to_int_type [static] char_type을 동등한 int_type으로 변환해요 (공용 정적 멤버 함수)
eq_int_type [static] 두 int_type 값을 비교해요 (공용 정적 멤버 함수)
eof [static] eof 값을 반환해요 (공용 정적 멤버 함수)
not_eof [static] 문자가 eof 값인지 확인해요 (공용 정적 멤버 함수)

참고 사항

CharTraits는 위에 나열된 타입과 함수를 직접 멤버로 정의할 것을 요구하지 않아요. 단지 X::type 같은 타입과 X::func(args) 같은 표현식이 유효하고 요구된 의미를 가져야 한다고 요구할 뿐이에요. 사용자 정의 문자 특성 클래스는 다른 문자 특성 클래스에서 파생되고 일부 멤버만 재정의할 수 있어요. 아래 예제를 참고하세요.

예제

사용자 정의 문자 특성은 대소문자를 구분하지 않는 비교를 제공하는 데 사용될 수 있어요.

#include <cctype>
#include <iostream>
#include <string>
#include <string_view>

struct ci_char_traits : public std::char_traits<char>
{
    static char to_upper(char ch)
    {
        return std::toupper((unsigned char) ch);
    }
    
    static bool eq(char c1, char c2)
    {
        return to_upper(c1) == to_upper(c2);
    }
    
    static bool lt(char c1, char c2)
    {
         return to_upper(c1) < to_upper(c2);
    }
    
    static int compare(const char* s1, const char* s2, std::size_t n)
    {
        while (n-- != 0)
        {
            if (to_upper(*s1) < to_upper(*s2))
                return -1;
            if (to_upper(*s1) > to_upper(*s2))
                return 1;
            ++s1;
            ++s2;
        }
        return 0;
    }
    
    static const char* find(const char* s, std::size_t n, char a)
    {
        const auto ua{to_upper(a)};
        while (n-- != 0) 
        {
            if (to_upper(*s) == ua)
                return s;
            s++;
        }
        return nullptr;
    }
};

template<class DstTraits, class CharT, class SrcTraits>
constexpr std::basic_string_view<CharT, DstTraits>
    traits_cast(const std::basic_string_view<CharT, SrcTraits> src) noexcept
{
    return {src.data(), src.size()};
}

int main()
{
    using namespace std::literals;
    
    constexpr auto s1 = "Hello"sv;
    constexpr auto s2 = "heLLo"sv;
    
    if (traits_cast<ci_char_traits>(s1) == traits_cast<ci_char_traits>(s2))
        std::cout << s1 << " and " << s2 << " are equal\n";
}

출력:

Hello and heLLo are equal

같이 보기

항목 설명
basic_string 문자 시퀀스를 저장하고 조작해요 (클래스 템플릿)
basic_string_view (C++17) 읽기 전용 문자열 뷰 (클래스 템플릿)
basic_istream 주어진 추상 장치(std::basic_streambuf)를 감싸고 고수준 입력 인터페이스를 제공해요 (클래스 템플릿)
basic_ostream 주어진 추상 장치(std::basic_streambuf)를 감싸고 고수준 출력 인터페이스를 제공해요 (클래스 템플릿)
basic_streambuf 원시 장치를 추상화해요 (클래스 템플릿)

더 알아보기 (Learn more)

cppreference