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++
내 답안 · 자동 저장

작성 후 위 해설 보기에서 모범 해설과 대조하세요.