8. 완벽한 전달(perfect forwarding)과 보편 참조, 참조 축약

난이도 중 해설 보기 →

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

결함 코드 · C++
// ============================================================================
// [내부동작 문제] C++ - 완벽한 전달(perfect forwarding)과 보편 참조
// ----------------------------------------------------------------------------
// 주제:
//   템플릿의 `T&&`(보편/전달 참조, forwarding reference), 템플릿 인자 추론, 참조 축약
//   (reference collapsing), 그리고 std::forward 의 역할을 예측하고 설명한다.
//
// 아래 프로그램에서 target 은 인자의 값 범주(value category)에 따라 서로 다른 오버로드가
// 선택된다. relayForward 는 std::forward 로 전달하고, relayPlain 은 그냥 이름으로 전달한다.
//
// 과제:
//   1) main 의 각 호출이 어떤 target 오버로드를 부르는지(출력 문자열)를 예측하라.
//   2) relayForward 에서 T 가 각각 무엇으로 추론되는지, 참조 축약이 어떻게 적용되는지
//      설명하라. (T&& 가 lvalue/rvalue 에 대해 각각 어떤 타입이 되는가)
//   3) relayPlain(42) 의 결과가 relayForward(42) 와 왜 달라지는지(이름 붙은 매개변수의
//      값 범주) 설명하라.
//   ※ 먼저 종이에 예측을 적은 뒤 실행 결과·answer.md 와 대조할 것. 컴파일/실행 가능하다.
// ============================================================================

#include <iostream>
#include <utility>

void target(int&)        { std::cout << "lvalue\n"; }
void target(const int&)  { std::cout << "const-lvalue\n"; }
void target(int&&)       { std::cout << "rvalue\n"; }

template <typename T>
void relayForward(T&& x) { target(std::forward<T>(x)); }   // 전달 참조 + forward

template <typename T>
void relayPlain(T&& x)   { target(x); }                    // 전달 참조, forward 없음

int main() {
    int a = 5;
    const int c = 7;

    relayForward(a);    // (1) ?
    relayForward(c);    // (2) ?
    relayForward(42);   // (3) ?

    relayPlain(a);      // (4) ?
    relayPlain(42);     // (5) ?
    return 0;
}
내 리뷰 · C++
내 답안 · 자동 저장

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