std:: forward
|
헤더 파일에 정의됨
<utility>
|
||
| (1) | ||
|
template
<
class
T
>
T && forward ( typename std:: remove_reference < T > :: type & t ) noexcept ; |
(C++11부터)
(C++14까지) |
|
|
template
<
class
T
>
constexpr T && forward ( std:: remove_reference_t < T > & t ) noexcept ; |
(C++14부터) | |
| (2) | ||
|
template
<
class
T
>
T && forward ( typename std:: remove_reference < T > :: type && t ) noexcept ; |
(C++11부터)
(C++14까지) |
|
|
template
<
class
T
>
constexpr T && forward ( std:: remove_reference_t < T > && t ) noexcept ; |
(C++14부터) | |
t 가 forwarding reference (cv-unqualified 함수 템플릿 매개변수에 대한 rvalue 참조로 선언된 함수 인자)인 경우, 이 오버로드는 인자를 호출 함수에 전달될 때 가졌던 value category 를 유지한 채 다른 함수로 전달합니다.
예를 들어, 다음과 같은 래퍼에서 사용될 경우, 템플릿은 아래와 같이 동작합니다:
template<class T> void wrapper(T&& arg) { // arg는 항상 lvalue입니다 foo(std::forward<T>(arg)); // T에 따라 lvalue 또는 rvalue로 전달 }
-
wrapper()호출 시 rvaluestd::string이 전달되면,T는std::string으로 추론되며 (std::string&,const std::string&, 또는std::string&&가 아님),std::forward는 rvalue 참조가foo에 전달되도록 보장합니다. -
wrapper()호출 시 const lvaluestd::string이 전달되면,T는const std::string&으로 추론되며,std::forward는 const lvalue 참조가foo에 전달되도록 보장합니다. -
wrapper()호출 시 non-const lvaluestd::string이 전달되면,T는std::string&으로 추론되며,std::forward는 non-const lvalue 참조가foo에 전달되도록 보장합니다.
이 오버로드는 (함수 호출과 같은) 표현식의 결과를, rvalue 또는 lvalue일 수 있는, 포워딩 참조 인수의 원래 값 범주로 전달할 수 있게 합니다.
예를 들어, 래퍼가 단순히 인자를 전달하지 않고, 인자에 대해 멤버 함수를 호출하고 그 결과를 전달하는 경우:
// 변환 래퍼 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; } // 이 오버로드에 대한 호출은 rvalue입니다 int& get() & { return i; } // 이 오버로드에 대한 호출은 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로 변환
(함수 템플릿) |
|
(C++11)
|
이동 생성자가 예외를 던지지 않는 경우 인수를 xvalue로 변환
(함수 템플릿) |