47. 멤버 함수의 참조 한정자(ref-qualifier)와 값 범주 기반 오버로드

난이도 중 해설 보기 →

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

결함 코드 · C++
// 문제 47 — 멤버 함수의 참조 한정자(ref-qualifier: & / &&)와 값 범주에 따른 오버로드
//
// 주제: 멤버 함수 뒤에 붙는 `&`, `&&`, `const &` 한정자는 무엇을 의미하는가?
//   같은 이름의 멤버 함수를 lvalue용(&)과 rvalue용(&&)으로 오버로드하면, 호출 대상
//   객체의 "값 범주(value category)" 에 따라 어떤 오버로드가 선택되는가?
//
// 과제:
//   1) 아래 프로그램의 출력을 정확히 예측하라(각 호출이 어떤 오버로드를 부르는지).
//   2) 멤버 함수 ref-qualifier 의 오버로드 해석 규칙을 값 범주 관점에서 설명하라.
//   3) 이 기능이 실무(예: 빌더 패턴, 임시 객체에서의 이동 최적화)에서 왜 유용한지 설명하라.

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

struct Payload {
    std::string data;

    // lvalue 객체에서 호출: 원본을 보존해야 하므로 복사해서 반환
    std::string get() const & {
        std::cout << "get() const& -> copy\n";
        return data;
    }
    // rvalue(임시/std::move된) 객체에서 호출: 원본이 곧 사라지므로 이동해서 반환
    std::string get() && {
        std::cout << "get() && -> move\n";
        return std::move(data);
    }
};

Payload makePayload() { return Payload{"temp"}; }

int main() {
    Payload lv{"lvalue"};

    std::string a = lv.get();               // (1)
    std::string b = makePayload().get();    // (2)
    std::string c = std::move(lv).get();    // (3)

    std::cout << a << " / " << b << " / " << c << "\n";
    return 0;
}
내 리뷰 · C++
내 답안 · 자동 저장

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