Namespaces
Variants

std::forward

cppreference.net에서
 
 
유틸리티 라이브러리
일반 유틸리티
관계 연산자 (C++20에서 폐기됨)
정수 비교 함수
(C++20)(C++20)(C++20)    
(C++20)
교체타입 연산
(C++14)
(C++11)
(C++11)
(C++11)
(C++17)
일반 어휘 타입
(C++11)
(C++17)
(C++17)
(C++17)
(C++11)
(C++17)
(C++23)



 
헤더 <utility>
template< class T >
T&& forward( typename std::remove_reference<T>::type& t ) noexcept;
에 정의됨 (1) (C++11부터)
(C++14까지)
template< class T >
constexpr T&& forward( std::remove_reference_t<T>& t ) noexcept;
(C++14부터)
template< class T >
T&& forward( typename std::remove_reference<T>::type&& t ) noexcept;
(2) (C++11부터)
(C++14까지)
template< class T >
constexpr T&& forward( std::remove_reference_t<T>&& t ) noexcept;
(C++14부터)
1) T에 따라 lvalue를 lvalue 또는 rvalue로 전달합니다.

t전달 참조 (cv-한정되지 않은 함수 템플릿 매개변수에 대한 rvalue 참조로 선언된 함수 인자)일 때, 이 오버로드는 인자를 호출 함수에 전달될 때 가졌던 값 종류로 다른 함수에 전달합니다.

예를 들어, 다음과 같은 래퍼에서 사용될 경우 템플릿은 아래에 설명된 대로 동작합니다:

template<class T>
void wrapper(T&& arg)
{
    // arg is always lvalue
    foo(std::forward<T>(arg)); // Forward as lvalue or as rvalue, depending on T
}
  • wrapper()에 대한 호출이 rvalue std::string를 전달하면, Tstd::string로 추론되고 (std::string&, const std::string&, 또는 std::string&&이 아님), std::forward은 rvalue 참조가 foo에 전달되도록 보장합니다.
  • wrapper()에 대한 호출이 const lvalue std::string를 전달하면, Tconst std::string&로 추론되고, std::forward은 const lvalue 참조가 foo에 전달되도록 보장합니다.
  • wrapper()에 대한 호출이 비-const lvalue std::string를 전달하면, Tstd::string&로 추론되고, std::forward은 비-const lvalue 참조가 foo에 전달되도록 보장합니다.
2) rvalue를 rvalue로 전달하고, rvalue를 lvalue로 전달하는 것을 금지합니다.

이 오버로드는 표현식(함수 호출 등)의 결과를 전달 참조 인자의 원래 값 종류로 전달할 수 있게 합니다. 이 결과는 rvalue 또는 lvalue일 수 있습니다.

예를 들어, 래퍼가 단순히 인자를 전달하는 대신 인자에 대해 멤버 함수를 호출하고 그 결과를 전달하는 경우:

// transforming wrapper
template<class T>
void wrapper(T&& arg)
{
    foo(forward<decltype(forward<T>(arg).get())>(forward<T>(arg).get()));
}

여기서 arg의 타입은 다음과 같을 수 있습니다.

struct Arg
{
    int i = 1;
    int  get() && { return i; } // call to this overload is rvalue
    int& get() &  { return i; } // call to this overload is lvalue
};

rvalue를 lvalue로 전달하려는 시도, 예를 들어 lvalue 참조 타입 T로 (2) 형식을 인스턴스화하는 것은 컴파일 타임 오류입니다.

참고 사항

자세한 내용은 template argument deduction 에서 전달 참조( T&& 가 함수 매개변수로 사용되는 경우)에 대한 특별 규칙과 forwarding references 에서 다른 세부 사항을 참조하십시오.

매개변수

t - 전달될 객체

반환값

static_cast < T && > ( t )

복잡도

상수.

예제

이 예제는 클래스 T 의 생성자 인자로 매개변수를 완벽 전달(perfect forwarding)하는 방법을 보여줍니다. 또한 매개변수 팩(parameter packs)의 완벽 전달도 함께 보여줍니다.

#include <iostream>
#include <memory>
#include <utility>
struct A
{
    A(int&& n) { std::cout << "rvalue overload, n=" << n << '\n'; }
    A(int& n)  { std::cout << "lvalue overload, n=" << n << '\n'; }
};
class B
{
public:
    template<class T1, class T2, class T3>
    B(T1&& t1, T2&& t2, T3&& t3) :
        a1_{std::forward<T1>(t1)},
        a2_{std::forward<T2>(t2)},
        a3_{std::forward<T3>(t3)}
    {}
private:
    A a1_, a2_, a3_;
};
template<class T, class U>
std::unique_ptr<T> make_unique1(U&& u)
{
    return std::unique_ptr<T>(new T(std::forward<U>(u)));
}
template<class T, class... U>
std::unique_ptr<T> make_unique2(U&&... u)
{
    return std::unique_ptr<T>(new T(std::forward<U>(u)...));
}
auto make_B(auto&&... args) // since C++20
{
    return B(std::forward<decltype(args)>(args)...);
}
int main()
{
    auto p1 = make_unique1<A>(2); // rvalue
    int i = 1;
    auto p2 = make_unique1<A>(i); // lvalue
    std::cout << "B\n";
    auto t = make_unique2<B>(2, i, 3);
    std::cout << "make_B\n";
    [[maybe_unused]] B b = make_B(4, i, 5);
}

출력:

rvalue overload, n=2
lvalue overload, n=1
B
rvalue overload, n=2
lvalue overload, n=1
rvalue overload, n=3
make_B
rvalue overload, n=4
lvalue overload, n=1
rvalue overload, n=5

참고 항목

(C++11)
인수를 xvalue로 변환
(함수 템플릿)
이동 생성자가 예외를 던지지 않는 경우 인수를 xvalue로 변환
(함수 템플릿)