본문 바로가기
개발/C++ (98,03,11,14,17,20,23)

Modern C++ : std::string_view (17, 20)

by snowoods 2025. 9. 1.

Modern C++

 

std::string_view

 

개요

std::string_view는 C++17에서 도입된 문자열 뷰 클래스로, 문자열 데이터에 대한 읽기 전용 뷰를 제공합니다. 메모리 할당 없이 문자열을 참조할 수 있어 성능이 중요한 상황에서 유용하게 사용됩니다.

 

C++ 버전별 주요 키워드 도입 시기

  • C++17: std::string_view가 표준 라이브러리에 추가됨
  • C++20: std::string_viewstarts_with(), ends_with() 등의 편의 함수 추가

 

내용 설명

std::string_view는 다음과 같은 특징을 가집니다:

  1. 메모리 할당 없음: 문자열 데이터를 소유하지 않고 참조만 함
  2. 가볍고 빠름: std::string보다 가볍고 복사 비용이 저렴
  3. 유효성 주의: 참조하는 문자열의 수명이 string_view보다 길어야 함
  4. SSO와의 차이점: SSO는 짧은 문자열을 스택에 저장하는 반면, string_view는 어떤 문자열이든 참조 가능

 

예제 코드

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

// 전역 operator new 오버로딩으로 메모리 할당 추적
void* operator new(std::size_t count) {
    if (count > 32)
        std::cout << "Allocating " << count << " bytes\n";
    return malloc(count);
}

// const std::string&를 사용한 함수
void process_with_string(const std::string& s) {
    std::cout << "Processing string: " << s << '\n';
}

// std::string_view를 사용한 함수
void process_with_string_view(std::string_view sv) {
    std::cout << "Processing string_view: " << sv << '\n';
}

int main() {
    // 문자열 리터럴 전달 시
    std::cout << "\n=== 문자열 리터럴 전달 ===\n";
    process_with_string("Hello, string!");        // 임시 string 객체 생성
    process_with_string_view("Hello, string_view!"); // 추가 할당 없음

    // 긴 문자열로 테스트
    const char* long_text = "This is a very long string that would cause allocation...";

    std::cout << "\n=== 긴 문자열 처리 ===\n";
    process_with_string(long_text);      // string 생성자에서 할당 발생
    process_with_string_view(long_text); // 할당 없음

    // string_view를 사용한 부분 문자열 처리
    std::cout << "\n=== 부분 문자열 처리 ===\n";
    std::string full_text = "The quick brown fox jumps over the lazy dog";
    std::string_view first_word(full_text.data(), 3);  // "The"
    std::string_view last_word(full_text.data() + full_text.rfind(' ') + 1);  // "dog"

    std::cout << "First word: " << first_word << '\n';
    std::cout << "Last word: " << last_word << '\n';

    return 0;
}

 

실행 결과

=== 문자열 리터럴 전달 ===
Allocating 32 bytes
Processing string: Hello, string!
Processing string_view: Hello, string_view!

=== 긴 문자열 처리 ===
Allocating 64 bytes
Processing string: This is a very long string that would cause allocation...
Processing string_view: This is a very long string that would cause allocation...

=== 부분 문자열 처리 ===
First word: The
Last word: dog

 

활용팁

  1. 함수 매개변수로 사용: const std::string& 대신 std::string_view를 사용하면 불필요한 복사와 메모리 할당을 피할 수 있습니다.
  2. 문자열 리터럴 처리: 문자열 리터럴을 다룰 때 std::string 대신 std::string_view를 사용하면 임시 객체 생성을 방지할 수 있습니다.
  3. 부분 문자열 참조: 큰 문자열의 일부를 참조할 때 std::string::substr() 대신 std::string_view를 사용하면 추가 할당 없이 효율적으로 처리할 수 있습니다.
  4. 주의사항:
    • 참조하는 원본 문자열의 수명이 string_view보다 길어야 합니다.
    • string_view는 읽기 전용이므로 문자열을 수정해야 한다면 std::string을 사용해야 합니다.
    • string_view를 멤버 변수로 사용할 때는 주의가 필요합니다.
  5. 성능 비교:
    • std::string: 문자열 소유, 메모리 할당 발생 가능
    • std::string_view: 문자열 참조만, 할당 없음
    • const char*: C 스타일 문자열, string_view만큼 가볍지만 길이 정보가 없음
  6. C++20 이후: std::string_viewstarts_with(), ends_with() 등의 편의 함수가 추가되어 더욱 강력해졌습니다.