✅ 1. std::string_view란?
C++17에서 도입된 std::string_view는 문자열을 복사하지 않고 참조하는 경량 래퍼입니다.
기존의 std::string과 const char*의 단점을 보완하며, 문자열을 더 효율적으로 처리할 수 있습니다.
📌 주요 특징:
✔ 문자열을 복사하지 않고 참조 → 빠르고 메모리 절약
✔ std::string, "문자열 리터럴", char* 등과 함께 사용 가능
✔ 읽기 전용 (mutable X)
📌 기본 문법:
#include <iostream>
#include <string_view>
void print(std::string_view sv) { // 복사 없이 문자열 참조
std::cout << sv << '\n';
}
int main() {
std::string str = "Hello, World!";
print(str); // std::string 전달
print("Hello, string_view!"); // 문자열 리터럴 전달
}
✅ 2. std::string vs. std::string_view 차이점
비교 항목 | std::string | std::string_view |
메모리 할당 | 문자열을 복사 | 참조만 유지 |
크기 | 동적 할당 | 작고 가벼움 (sizeof(string_view) == 16 정도) |
변경 가능 여부 | 변경 가능 | 읽기 전용 |
종료 문자 (\0) | 항상 포함 | 포함되지 않을 수도 있음 |
성능 | 문자열 복사 비용 있음 | 빠르고 효율적 |
📌 std::string은 힙에 메모리를 할당하지만, std::string_view는 단순한 포인터와 길이만 저장함.
📌 "임시 문자열을 전달할 때 std::string_view 사용하면 불필요한 복사를 방지할 수 있음.
✅ 3. std::string_view 기본 사용법
📌 (1) std::string_view 생성
#include <iostream>
#include <string_view>
int main() {
std::string_view sv1 = "Hello, World!"; // 문자열 리터럴 사용
std::string str = "Hello, C++!";
std::string_view sv2 = str; // std::string을 참조
std::cout << sv1 << '\n';
std::cout << sv2 << '\n';
}
✅ 설명:
- sv1은 문자열 리터럴을 참조.
- sv2는 std::string을 참조.
- 문자열 복사가 발생하지 않음.
📌 (2) std::string_view의 주요 메서드
std::string_view는 std::string과 비슷한 메서드를 제공함.
#include <iostream>
#include <string_view>
int main() {
std::string_view sv = "Hello, string_view!";
std::cout << "Size: " << sv.size() << '\n'; // 문자열 길이
std::cout << "First character: " << sv[0] << '\n'; // 문자 접근
std::cout << "Substring: " << sv.substr(7, 6) << '\n'; // 부분 문자열
std::cout << "Starts with 'Hello'? " << sv.starts_with("Hello") << '\n';
std::cout << "Ends with 'view'? " << sv.ends_with("view") << '\n';
}
✅ 출력 결과:
Size: 19
First character: H
Substring: string
Starts with 'Hello'? 1
Ends with 'view'? 1
📌 std::string_view는 substr()을 사용하여 부분 문자열을 빠르게 생성 가능.
📌 starts_with() 및 ends_with()를 통해 문자열 접두사/접미사 확인 가능 (C++20)
📌 (3) std::string_view와 std::string 변환
std::string_view → std::string 변환 (복사 발생)
std::string_view sv = "Hello, World!";
std::string s = std::string(sv); // 명시적 변환 필요
📌 변환 시 문자열 복사가 발생하므로 주의!
std::string → std::string_view 변환 (복사 없음)
std::string str = "Hello";
std::string_view sv = str; // 참조만 유지 (빠름)
📌 std::string_view는 std::string을 참조하므로 복사 비용이 없음.
✅ 4. std::string_view 사용 시 주의점
❌ (1) Dangling Reference 문제
std::string_view getView() {
std::string str = "Temporary";
return str; // ❌ Dangling Reference 발생
}
int main() {
std::string_view sv = getView(); // sv는 해제된 메모리를 가리킴
std::cout << sv << '\n'; // ❌ 미정의 동작 (UB)
}
✅ 해결 방법:
- std::string이 스코프를 벗어나기 전에 std::string_view를 사용해야 함.
- 또는 std::string을 직접 반환하여 복사를 허용.
❌ (2) Null-terminated (\0) 보장되지 않음
std::string_view sv = "Hello, World!";
std::cout << sv.data() << '\n'; // 정상
✅ data()는 널 종료 문자 (\0)를 보장하지 않음.
✅ C-스타일 문자열 (char*) 필요하면 std::string으로 변환 후 사용!
✅ 5. std::string_view의 활용 예시
📌 (1) 함수 매개변수 최적화
void print(std::string_view sv) { // 문자열 복사 없음
std::cout << sv << '\n';
}
int main() {
std::string str = "Hello";
print(str); // std::string 전달
print("Hello, World!"); // 문자열 리터럴 전달
}
📌 매개변수 타입을 std::string_view로 선언하면 std::string과 "리터럴" 모두 지원 가능.
📌 문자열 복사 비용 절감!
📌 (2) 텍스트 파싱 및 문자열 처리
#include <iostream>
#include <string_view>
void parse(std::string_view sv) {
while (!sv.empty()) {
auto pos = sv.find(' ');
std::cout << sv.substr(0, pos) << '\n';
if (pos == std::string_view::npos) break;
sv.remove_prefix(pos + 1);
}
}
int main() {
parse("Hello World from string_view!");
}
📌 remove_prefix(n)을 사용하면 문자열 복사 없이 앞부분을 제거 가능.
📌 텍스트 파싱 성능이 향상됨.
🔥 정리
✅ std::string_view는 문자열을 참조하는 가벼운 객체.
✅ 문자열 복사를 방지하여 성능 최적화 가능.
✅ 읽기 전용이므로 변경 불가능.
✅ 매개변수 전달, 텍스트 파싱 등에 활용하면 성능 향상!
✅ Dangling Reference 문제에 주의해야 함.
🚀 C++에서 더 효율적인 문자열 처리를 원한다면? std::string_view를 사용하자! 🚀
'프로그래밍 > C,C++' 카테고리의 다른 글
[Modern C++20] concept (0) | 2025.04.08 |
---|---|
[Modern C++20] 삼중 비교 연산자(Three-Way Comparison) (0) | 2025.03.28 |
[Modern C++] 람다 표현식 (Lambda Expression) (0) | 2025.03.26 |
[Modern C++] decltype (0) | 2025.03.25 |
[Modern C++] STL 자료구조 (0) | 2025.03.24 |