2. 이동 의미론과 복사 생략(RVO/NRVO)
난이도 중 해설 보기 →
결함을 모두 찾고 원인·수정안·더 나은 설계를 제시하라. 마커
(A)(B) 는 주목 위치 힌트다.
결함 코드 · C++
// ============================================================================
// [언어 내부동작 문제] C++ - 이동 의미론과 복사 생략(RVO/NRVO)
// ----------------------------------------------------------------------------
// 주제:
// 값 반환에서 일어나는 복사 생략(copy elision): C++17 의 보장된 RVO(prvalue),
// 이름있는 지역의 NRVO, 그리고 return 문에서의 std::move 가 무엇을 바꾸는가.
//
// 과제:
// 1) 아래 프로그램을 g++ -std=c++17 로 빌드해 실행했을 때 출력되는
// ctor/copy/move/dtor 의 "정확한 순서"를 예측해 적어라(빈 name 출력에도 주의).
// 2) makeRVO / makeNRVO / makeMovedReturn 각각에서 복사·이동이 몇 번 일어나는지,
// 왜 그런지(보장된 elision vs 선택적 NRVO vs std::move 의 영향)를 설명하라.
// 3) "return std::move(local)" 이 왜 이득이 아니라 손해가 되기 쉬운지 설명하라.
// (먼저 직접 예측·설명을 적은 뒤 answer.md 와 대조할 것)
// ============================================================================
#include <iostream>
#include <string>
#include <utility>
struct Tracer
{
std::string name;
Tracer(std::string n) : name(std::move(n)) { std::cout << "ctor " << name << "\n"; }
Tracer(const Tracer& o) : name(o.name) { std::cout << "copy " << name << "\n"; }
Tracer(Tracer&& o) noexcept : name(std::move(o.name)) { std::cout << "move " << name << "\n"; }
~Tracer() { std::cout << "dtor " << name << "\n"; }
};
Tracer makeRVO()
{
return Tracer("A"); // prvalue 반환
}
Tracer makeNRVO()
{
Tracer t("B");
return t; // 이름있는 지역 반환
}
Tracer makeMovedReturn()
{
Tracer t("C");
return std::move(t); // 반환에 std::move
}
int main()
{
Tracer a = makeRVO();
std::cout << "---\n";
Tracer b = makeNRVO();
std::cout << "---\n";
Tracer c = makeMovedReturn();
std::cout << "===\n";
return 0;
} 내 리뷰 · C++
내 답안 · 자동 저장
작성 후 위 해설 보기에서 모범 해설과 대조하세요.