39. std::optional 의 내부 동작과 값 의미론
난이도 중 해설 보기 →
결함을 모두 찾고 원인·수정안·더 나은 설계를 제시하라. 마커
(A)(B) 는 주목 위치 힌트다.
결함 코드 · C++
// 주제: std::optional 의 내부 동작과 값 의미론.
//
// 과제:
// 1) 아래 프로그램의 출력을 정확히 예측하라(생성/이동/소멸 로그 포함).
// 2) optional<T> 가 T 를 어디에(힙 vs 자기 저장소) 담는지, has_value/engaged 상태,
// emplace/reset 이 담긴 객체의 생성자·소멸자를 언제 호출하는지 예측·설명하라.
// 3) operator*/operator-> 와 value()의 차이(전제조건 vs 예외), 그리고 빈 optional 에
// 대한 fallback 이 어느 시점에 평가되는지 설명하라.
#include <iostream>
#include <optional>
#include <string>
struct Tracked {
std::string name;
Tracked(std::string n) : name(std::move(n)) { std::cout << "ctor " << name << "\n"; }
Tracked(const Tracked& o) : name(o.name) { std::cout << "copy " << name << "\n"; }
Tracked(Tracked&& o) noexcept : name(std::move(o.name)) { std::cout << "move " << name << "\n"; }
~Tracked() { std::cout << "dtor " << name << "\n"; }
};
std::string fallback() { std::cout << "fallback()\n"; return "FB"; }
int main() {
std::cout << "-- 1 --\n";
std::optional<Tracked> o; // (관찰) 담긴 값 유무
std::cout << "engaged=" << o.has_value() << "\n";
std::cout << "-- 2 --\n";
o.emplace("A"); // (A)
std::cout << "engaged=" << o.has_value() << "\n";
std::cout << "-- 3 --\n";
o.reset(); // (B)
std::cout << "engaged=" << o.has_value() << "\n";
std::cout << "-- 4 --\n";
std::optional<Tracked> p{Tracked("B")}; // (C) 임시로부터 초기화
std::cout << "operator-> 접근\n";
std::string s = p->name;
std::cout << "name=" << s << "\n";
std::cout << "-- 5 --\n";
std::optional<Tracked> q; // 비어 있음
std::string r = q ? q->name : fallback(); // (D) 분기 평가
std::cout << "r=" << r << "\n";
std::cout << "-- end --\n";
return 0;
} 내 리뷰 · C++
내 답안 · 자동 저장
작성 후 위 해설 보기에서 모범 해설과 대조하세요.