본문 바로가기

프로그래밍/C++

C++11 RValue Reference - 우측값 참조



=> 1+2;


이와 같이 3이라는 숫자가 생성되자 마자 사라지는 값을 c++에서는 우측값이라고 한다.


=> int sum = 1+2;


반면 sum과 같이 기억되는 변수를 왼쪽값이라고 한다.



c++를 처음 배울때 값에 의한 전달, 참조에 의한 전달이라는 것을 배우는데,


여기서 참조전달은 정확히 이야기하면 왼쪽값 레퍼런스 전달을 의미한다.


예를 들어,


void SetName(string& name) {


m_name = name; 

}


SetName의 파라미터는 name이라는 왼쪽값 참조를 전달하고 있다.




C++11 에서는 오른쪽값 레퍼런스도 가능하게 하였는데,


표시는 기존의 &와 비슷한 &&를 사용한다.




int nCount;                          // nCount는 왼쪽값


int& lrefValue1 = nCount;       // 왼쪽값이므로 문제 없음

int& lrefValue2 = 10;             // 10은 오른쪽값이므로 에러


int&& rrefValue1 = 10;          // 10은 오른쪽값이므로 문제 없음

int&& rrefValue2 = nCount;    // nCount는 왼쪽값이므로 에러




이와 더불어 &&을 이용한 이동연산자, 이동생성자 및 몇가지 함수도 추가되었다.


참고로 이동생성자의 경우, 기존의 복사생성자보다 월등히 빠르다.


이동생성자 - http://honestgame.tistory.com/86




std::move() - 좌측값을 우측값으로 캐스팅, 그리고 좌측값을 비운다.


http://en.cppreference.com/w/cpp/utility/move


std::forward() - 템플릿함수 파라미터를 그대로 다른 함수에 전달


http://en.cppreference.com/w/cpp/utility/forward




#include <iostream>
#include <memory>
#include <utility>
#include <array>
 
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_unique(U&&... u)
{
    return std::unique_ptr<T>(new T(std::forward<U>(u)...));
}
 
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_unique<B>(2, i, 3);
}


std::forward() 의 예제이다.


B 클래스 생성인자에  왼쪽값, 오른쪽값을 섞어서 전달해주고 있는데


실제 결과도 정확히 처리되는 것을 볼 수 있다.


이것을 사용하지 않으면 


템플릿인자가 왼쪽값인지, 오른쪽값인지 의도하지 않는 방향으로 캐스팅되어


처리가 되므로, 명확히 이게 왼쪽값이다, 또는 오른쪽값이다 라는 것을


정확히 지정해 주는 역할이 필요하다.





그밖의 참조사이트


https://msdn.microsoft.com/ko-kr/library/dd293668.aspx


http://egloos.zum.com/frompt/v/2765424


http://itguru.tistory.com/189