std::optional: 값이 없을 수 있는 결과 표현하기
15강. std::optional: 값이 없을 수 있는 결과 표현하기
이번 강의에서 해결할 문제
아이템을 찾지 못했을 때 -1을 반환하면 실제 수량 -1과 실패가 같은 타입에 섞입니다. 빈 문자열이나 null 포인터도 값의 의미와 실패 원인을 흐릴 수 있습니다.
학습 목표
optional<T>가 값 또는 값 없음 상태를 표현함을 설명합니다.has_value, 조건식,value_or로 결과를 확인합니다.- 값 존재 확인 전 무조건 꺼내는 코드를 피합니다.
먼저 알아야 할 핵심 개념
std::optional<T>는 T 값이 있을 수도 없을 수도 있는 값 타입입니다. 값 없음은 std::nullopt로 표현합니다. 포인터 소유권을 나타내는 도구가 아니라 조회 실패처럼 정상적으로 가능한 부재를 반환 계약에 드러내는 도구입니다.
가장 작은 실행 가능한 예제
#include <iostream>
#include <optional>
#include <string>
#include <unordered_map>
std::optional<int> findCount(
const std::unordered_map<std::string, int>& inventory,
const std::string& name) {
const auto found = inventory.find(name);
if (found == inventory.end()) {
return std::nullopt;
}
return found->second;
}
int main() {
const std::unordered_map<std::string, int> inventory{{"Potion", 3}};
std::cout << findCount(inventory, "Potion").value_or(0) << ' '
<< findCount(inventory, "Key").value_or(0) << '\n';
}
핵심 코드 줄별 설명
- 반환형에서 값이 없을 수 있음을 바로 알 수 있습니다.
- map의
find는 목록을 변경하지 않고 키를 조회합니다. - 실패하면
nullopt, 성공하면 실제 수량을 반환합니다. value_or(0)은 값이 없을 때만 기본값 0을 사용합니다.- 호출자가 부재를 오류로 볼지 기본값으로 처리할지 결정합니다.
실행 결과와 값 변화
3 0
두 번째 결과가 0이어도 실제로 수량 0인 아이템인지 값이 없었는지는 value_or 이후 구분되지 않습니다. 구분이 필요하면 optional 자체를 조건식으로 검사합니다.
단계별 실습
실습 목표
플레이어 이름으로 점수를 찾고 부재 상태를 별도 문장으로 처리합니다.
시작 전 상태와 실행 방법
unordered_map<string, int>에 플레이어 한 명을 넣고 예제 함수를 복사합니다.
1단계: 최소 코드 작성
존재하는 이름을 찾아 optional 값이 있으면 점수를 출력합니다.
2단계: 값 또는 조건을 바꿔 결과 비교
없는 이름을 조회해 not found 분기가 실행되는지 확인합니다.
3단계: 작은 기능 확장
점수가 0인 플레이어를 추가해 값 0과 값 없음이 구분되는지 확인합니다.
4단계: 스스로 해결하기
가장 높은 점수를 반환하되 목록이 비어 있으면 nullopt를 반환하는 함수를 작성하세요.
막혔을 때
값이 없는 optional에 .value()를 호출하면 예외가 발생합니다. if (result) 또는 has_value()로 검사하거나 의미 있는 기본값이 있을 때만 value_or를 사용합니다.
흔한 실수와 해결 방법
- 검사 없이 value 호출: 값 존재를 먼저 확인합니다.
- 모든 실패를 nullopt 하나로 축약: 실패 이유가 여러 개면 별도 오류 타입이 필요합니다.
- optional을 포인터 소유 도구로 사용: 객체 소유권은 값·스마트 포인터 설계로 해결합니다.
게임 개발 연결
선택된 슬롯, 찾은 아이템 ID, 레이캐스트 결과처럼 결과가 없을 수 있는 조회에 적합합니다. 엔진 API가 이미 null 포인터나 전용 결과 구조를 사용한다면 경계에서 의미를 변환하고 프로젝트 규칙을 일관되게 유지합니다.
이해 점검 질문 3개
optional<int>가 정수 -1 반환보다 명확한 이유는 무엇인가요?value_or를 사용하면 어떤 정보가 사라질 수 있나요?- 여러 실패 원인을 전달해야 할 때 optional만으로 부족한 이유는 무엇인가요?
핵심 요약
optional은 값의 부재를 정상적인 반환 상태로 표현합니다. 호출자는 존재 여부를 확인하고, 기본값으로 합쳐도 되는지 또는 별도 처리가 필요한지 결정합니다.
다음 강의 연결
16강. variant에서 값이 여러 허용 타입 중 정확히 하나일 때 타입 안전하게 분기합니다.
std::optional: 값이 없을 수 있는 결과 표현하기 미니 퀴즈
선택 즉시 정답과 해설을 확인할 수 있습니다. 결과는 이 브라우저에만 저장됩니다.
학습을 마쳤나요?
직접 실습과 점검 질문까지 확인한 뒤 완료로 표시하세요.