전체 코드

🚀 1. 개요

C++11에서 도입된 전달 참조(Forwarding Reference)왼값(lvalue)과 오른값(rvalue)을 모두 처리할 수 있는 유연한 참조입니다.
이 문법은 템플릿 함수와 auto&&에서만 적용되며, std::forward를 활용하면 완벽한 전달(Perfect Forwarding)이 가능합니다.
전달 참조(T&&)왼값 참조 또는 오른값 참조로 동작 가능
std::forward<T> → 원본 타입이 왼값이면 복사, 오른값이면 이동을 수행

이 문서에서는 전달 참조와 std::forward의 원리를 예제 코드와 함께 상세히 분석하겠습니다.


📂 2. 코드 분석

🎯 클래스 Knight

class Knight
{
public:
    Knight() { cout << "기본 생성자" << endl; }
    Knight(const Knight&) { cout << "복사 생성자" << endl; }
    Knight(Knight&&) noexcept { cout << "이동 생성자" << endl; }
};

Knight 클래스

  • 기본 생성자"기본 생성자" 출력
  • 복사 생성자"복사 생성자" 출력 (객체가 복사될 때 호출됨)
  • 이동 생성자"이동 생성자" 출력 (객체가 이동될 때 호출됨)

🎯 오른값 참조 함수

void Test_RValueRef(Knight&& k) 
{
}

오른값 참조(rvalue reference) 함수

  • 오른값(rvalue)만 받을 수 있음Test_RValueRef(k1); 컴파일 에러 발생
  • std::move(k1)를 사용하여 강제로 오른값으로 캐스팅하면 전달 가능

🎯 복사 전달 함수

void Test_Copy(Knight k)
{
}

복사 전달 함수

  • Knight 객체를 값(pass-by-value)으로 전달하여 복사 생성자가 호출됨
  • 복사 비용이 발생할 수 있으므로 성능이 중요한 경우 std::move 또는 std::forward를 고려해야 함

🎯 전달 참조 함수 (Forwarding Reference)

template<typename T>
void Test_ForwardingRef(T&& param)
{
    Test_Copy(std::forward<T>(param)); // 왼값이면 복사, 오른값이면 이동
    Test_Copy(param);                  // 항상 복사
    Test_Copy(std::move(param));       // 항상 이동
}

전달 참조(Forwarding Reference) 함수

  • T&& param이 전달 참조로 동작하며 왼값과 오른값을 모두 처리 가능
  • std::forward<T>(param)
    • param왼값 참조이면 복사
    • param오른값 참조이면 이동
  • std::move(param)
    • 항상 이동(왼값이어도 이동)

🎯 추가 템플릿 함수

//template<typename T, typename T2>
//void Test_ForwardingRef(T&& param, T2&& param2) 
//{
//	//TODO
//	
//}
//void Test_ForwardingRef(const T&& param) // 오른값 참조로 동작
//{
//
//}

여러 개의 전달 참조 매개변수 처리

  • 여러 개의 인자를 전달받는 경우에도 전달 참조를 활용할 수 있음
  • const T&& param → 이 경우 전달 참조가 아니라 오른값 참조로 동작

🎯 main() 함수 분석

int main()
{

프로그램 실행의 시작점.


🎯 오른값 참조 함수 호출

    Knight k1;
    //Test_RValueRef(k1); // 에러: 오른값 참조 함수에 왼값 전달 불가
    Test_RValueRef(std::move(k1)); // 이동 가능

오른값 참조 함수 실행

  • Test_RValueRef(k1); → 컴파일 오류 (왼값을 오른값 참조 함수에 전달 불가)
  • Test_RValueRef(std::move(k1));std::move를 사용하면 정상적으로 이동 가능

🎯 전달 참조(T&&)와 auto&&

    //Test_ForwardingRef(k1); // Knight의 왼값 참조
    //Test_ForwardingRef(std::move(k1)); // Knight의 오른값 참조

    auto&& k2 = k1;
    auto&& k3 = std::move(k1);

전달 참조의 특성

  • Test_ForwardingRef(k1); → 왼값 참조로 전달
  • Test_ForwardingRef(std::move(k1)); → 오른값 참조로 전달
  • auto&&는 전달된 값의 타입에 따라 왼값 참조 또는 오른값 참조로 자동 추론
    • auto&& k2 = k1;k2Knight& (왼값 참조)
    • auto&& k3 = std::move(k1);k3Knight&& (오른값 참조)

🎯 전달 참조와 이동 연산자

    Knight& k4 = k1; // 왼값 참조
    Knight&& k5 = std::move(k1); // 오른값 참조
    //k5 자체는 왼값
    Test_RValueRef(std::move(k5)); // 이동 가능

std::move 사용

  • k5Knight&&로 선언되었지만 변수 자체는 왼값으로 간주됨
  • std::move(k5);k5오른값으로 변환하여 이동 가능

🎯 전달 참조 활용 예제

    Test_ForwardingRef(k1); // 왼값 전달
    Test_ForwardingRef(std::move(k1)); // 오른값 전달

전달 참조(T&&) 활용

  • k1을 전달하면 왼값 참조로 추론되어 복사 생성자 호출
  • std::move(k1)을 전달하면 오른값 참조로 추론되어 이동 생성자 호출

profile
李家네_공부방

0개의 댓글