forward — std::forward

forward — std::forward

std::forward완전 전달(perfect forwarding)을 위해, 인수의 원래 값 종류(lvalue/rvalue)를 그대로 유지하면서 전달하는 함수예요. C++11에서 도입됐어요. <utility> 헤더에 있어요.

템플릿 인자를 다른 함수로 "있는 그대로" 포워딩할 때 사용해요.

출처: cppreference

본문

// <utility> 헤더, C++11
template< class T >
constexpr T&& forward( std::remove_reference_t<T>& t ) noexcept;

template< class T >
constexpr T&& forward( std::remove_reference_t<T>&& t ) noexcept;

사용 예 — 완전 전달 팩토리

#include <utility>
#include <memory>

// args를 그대로 T 생성자에 전달
template<typename T, typename... Args>
std::unique_ptr<T> make(Args&&... args) {
    return std::make_unique<T>(std::forward<Args>(args)...);
}

인자에 std::forward를 걸면, lvalue로 들어온 인자는 lvalue로, rvalue로 들어온 인자는 rvalue로 그대로 전달돼요. 이렇게 해야 이동·복사가 올바르게 선택돼요.

forwarding reference

template<typename T>
void wrapper(T&& x) {  // T&&는 forwarding reference
    inner(std::forward<T>(x));   // 값 종류 유지 전달
}

int n = 5;
wrapper(n);          // T=int& → lvalue 전달
wrapper(5);          // T=int  → rvalue 전달

forward vs move

  • std::move(x)항상 rvalue로.
  • std::forward<T>(x)T가 lvalue 참조면 lvalue, 아니면 rvalue. (조건부)
void g(int&);
void g(int&&);

template<typename T>
void f(T&& t) {
    g(std::forward<T>(t));   // 호출부 값 종류에 맞는 g 선택
}

주의

  • std::forward는 반드시 같은 타입의 템플릿 인자를 명시해 사용해요 (forward<T>).
  • forwarding reference(T&&) 매개변수에만 의미가 있어요.

std::forward는 제네릭 코드에서 인자의 값 종류를 잃지 않고 전달하는 완전 전달의 핵심 도구예요. 래퍼·팩토리·타입 안전한 포워딩에 필수적이에요.

더 알아보기 (Learn more)

cppreference