9. 예외 안전성과 noexcept, vector 재할당의 move_if_noexcept
난이도 최상 해설 보기 →
결함을 모두 찾고 원인·수정안·더 나은 설계를 제시하라. 마커
(A)(B) 는 주목 위치 힌트다.
결함 코드 · C++
// ============================================================================
// [내부동작 문제] C++ - 예외 안전성과 noexcept, vector 재할당의 move_if_noexcept
// ----------------------------------------------------------------------------
// 주제:
// std::vector 가 용량을 넘겨 재할당(reallocation)할 때, 기존 원소들을 새 버퍼로 옮기는
// 방식이 "이동"이냐 "복사"냐를 무엇이 결정하는지 예측하고 설명한다. 강한 예외 안전성
// (strong exception guarantee)과 noexcept, std::move_if_noexcept 의 관계가 핵심이다.
//
// 두 타입은 이동 생성자만 다르다:
// - Throwing : 이동 생성자에 noexcept 가 없음(던질 수 있다고 간주)
// - NoexceptMove : 이동 생성자가 noexcept
// 각 생성자는 호출될 때 "copy"/"move" 를 출력한다.
//
// 과제:
// 1) 아래 두 시나리오에서 "-- trigger realloc --" 이후 줄들이 각각 무엇을 출력할지
// 예측하라(기존 2개 원소가 새 버퍼로 옮겨질 때 copy 인가 move 인가).
// 2) 왜 이동 생성자의 noexcept 여부가 vector 재할당의 선택을 바꾸는지, 강한 예외
// 안전성 관점에서 설명하라.
// 3) 게임서버에서 핫한 컨테이너 원소 타입에 이 사실이 주는 실무적 함의를 적어라.
// ※ 먼저 예측을 적은 뒤 실행 결과·answer.md 와 대조할 것. 컴파일/실행 가능하다.
// ============================================================================
#include <iostream>
#include <vector>
struct Throwing {
Throwing() {}
Throwing(const Throwing&) { std::cout << "copy\n"; }
Throwing(Throwing&&) { std::cout << "move\n"; } // noexcept 없음
};
struct NoexceptMove {
NoexceptMove() {}
NoexceptMove(const NoexceptMove&) { std::cout << "copy\n"; }
NoexceptMove(NoexceptMove&&) noexcept { std::cout << "move\n"; }
};
template <typename T>
void grow(const char* label) {
std::cout << "[" << label << "]\n";
std::vector<T> v;
v.reserve(2);
v.emplace_back(); // 제자리 생성
v.emplace_back(); // 제자리 생성 (capacity=2 가득)
std::cout << "-- trigger realloc --\n";
v.emplace_back(); // capacity 초과 → 재할당, 기존 2개 이전
}
int main() {
grow<Throwing>("Throwing");
grow<NoexceptMove>("NoexceptMove");
return 0;
} 내 리뷰 · C++
내 답안 · 자동 저장
작성 후 위 해설 보기에서 모범 해설과 대조하세요.