1. What is it?

A reference that may resolve to either an lvalue reference or an rvalue reference.

It has a form of T&& for some deduced type T.

 

2. lvalue reference일지 rvalue reference일지를 결정하는 것은?

Initializer가 결정한다. Initializer가 lvalue이면 lvalue reference, rvalue이면 rvalue reference가 된다.

 

이를 좀 더 길게 설명하면,

universal reference인 template parameter deduction에서, type T의 lvalue는 type T&로 deduce되고, type T의 rvalue는 type T로 deduce된다.

 

예를 들어, T가 int일 때, rvalue인 경우 T&& -> int&&가 되어 rvalue reference가 된다.

lvalue일 경우, T&& -> int& &&가 되는데, reference collapsing에 의하여 int&, 즉 lvaue reference가 된다.

 

3. Reference collapsing

type deduction을 하다가 reference to reference가 발생하게 되는데, 다음 4가지가 있다.

A. rvalue reference to rvalue reference(RR)

B. rvalue reference to lvalue reference(RL)

C. lvalue reference to rvalue reference(LR)

D. lvalue reference to lvalue reference(LL)

 

A의 경우만 rvalue reference이고, 나머지 3가지의 경우 lvalue reference가 된다.

 

 

4. Perfect forwarding

 

void foo(const Widget&); // (1)

void foo(Widget&&); // (2)

void func0(Widget&& arg)

{

    // how to call (2)?

    foo(std::move(arg));

}

 

여기서 argument의 rvalueness를 이용하고 싶다면 std::move()를 사용해야 한다.

 

func0의 arg의 type은 rvalue reference이지만 arg 자체는 lvalue이기 때문이다.

 

그럼 만약 universal reference가 사용되는 template이라면 어떻게 하나?

 

template<typename T>

void func1(T&& arg)

{

    // how to forward the rvalueness or lvalueness to bar()?

    bar(std::forward<T>(arg));

}

이번에는 std::move()를 사용할 수가 없다. 왜냐하면 universal reference(T&&)가 lvalue reference가 될 지, rvalue reference가 될 지 모르기 때문이다.

즉, arg의 type을 그대로 bar에게 넘겨줘야 한다(perfect forwarding).

이를 위해 std::forward<>()를 사용한다.

'programming > C++' 카테고리의 다른 글

std::atomic  (0) 2013.02.18
C++11 cheat sheet  (0) 2013.02.18
shared_ptr, unique_ptr  (0) 2013.02.18
std::async and std::future 쓸 때...  (0) 2013.02.18
constexpr  (0) 2013.02.18
Posted by 무한자전거
,