50. std::move 의 정체와 const 객체의 "이동"

난이도 상 해설 보기 →

결함을 모두 찾고 원인·수정안·더 나은 설계를 제시하라. 마커 (A)(B) 는 주목 위치 힌트다.

결함 코드 · C++
// ============================================================================
// [언어 내부동작 문제] C++ — std::move 의 정체와 const 객체의 "이동"
// ----------------------------------------------------------------------------
// 주제:
//   std::move 는 무엇을 하는가? 아래 프로그램에서 각 생성자 호출이 복사(COPY)인지
//   이동(MOVE)인지, 그리고 그 이유(오버로드 해석과 값 범주)를 설명하라.
//
// 과제:
//   1) 표준 출력에 찍히는 줄을 순서대로 예측하라.
//   2) "-- move const --" 구간에서 왜 그런 결과가 나오는지, std::move 가 실제로
//      무엇을 반환하며 어떤 생성자가 선택되는지 설명하라.
//   3) 이동 후 원본 객체(moved-from)의 상태는 어떻게 규정되는지 설명하라.
//
// 빌드/실행: g++ -std=c++17 problem.cpp && ./a.out
// ============================================================================

#include <iostream>
#include <string>
#include <utility>

struct W {
    std::string tag;
    explicit W(std::string t) : tag(std::move(t)) { std::cout << "ctor " << tag << "\n"; }
    W(const W& o) : tag(o.tag) { std::cout << "COPY " << tag << "\n"; }
    W(W&& o) noexcept : tag(std::move(o.tag)) { std::cout << "MOVE " << tag << "\n"; }
};

int main() {
    W a("a");
    const W b("b");

    std::cout << "-- move non-const --\n";
    W c = std::move(a);
    std::cout << "a.tag after move = [" << a.tag << "]\n";

    std::cout << "-- move const --\n";
    W d = std::move(b);
    std::cout << "b.tag after move = [" << b.tag << "]\n";

    std::cout << "-- done --\n";
    (void)c; (void)d;
    return 0;
}
내 리뷰 · C++
내 답안 · 자동 저장

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