C에서 R-value 는
오른쪽에 있는 값.
L-value 는
왼쪽에 있는 값이다.
int a=3;
일 경우 R-value는 3, L-value 는 a 가 된다.
C++에서는 R-value는 사라지는 값
L-value는 사라지지 않는 값.
l value - 고유하면서 움직일 수 없는 값
x value - 고유하면서 움직일 수 있는 값
pr value - 순수한 값
gl value - 다른 조건 없이 고유하기만 하면 됨
l-value <-- gl-value --> xvalue
xvalue <-- r-value --> pr value
이런식으로 그림이 그려진다.
int x-3;
const int y = x;
int z = x+y;
int* p = &x;
cout << string("Hello");
++x;
x++;
여기서 R-value 는
진하게 한것이다.
x++; 가 R 밸류인 이유는 x 가 연산후에 값이 증가시키므로 기존 x 값에 대한 연산후에 증가한다.
따라서 기존 x 값을 저장할 임시 객체가 생성되고, 사라지므로 x++; 는 R-value 이다.
Q. Rvalue reference 는 Lvalue 일까 Rvalue 일까?
A. Lvalue (Rvalue =/= Rvalue Reference)
- 코드 곳곳에서 발생하는 불필요한 Rvalue 복사과정, 이로 인한 오버헤드
Q. 아래의 코드에서 오버헤드는 총 몇번 발생할까?
std::string a,b = "Hello ", c = "world";
a=b+c;
std::string appendString(std::string param);
std;:string result = appendString("Hello")
std::string a,b = "Hello ", c = "world";
a=b+c;
std::string appendString(std::string param);
std;:string result = appendString("Hello")
총 3번 발생한다.
임시객체를 이용한 불필요한 연산때문에 낭비가 일어난다.
이를 막으려고 Move Semantics 라는게 있다.
Move Semantics 란?
문자열의 직접적인 복사가 아닌, 포인터의 이동으로 낭비를 막는것.
A-1. Move 생성자, Move 대입 연산자를 구현후 사용.
A-2. Rvalue Reference를 파라미터로 받는 함수 사용.
--> 이렇게 할 경우, 컨테이너에 객체를 삽입할 때 더이상 포인터를 넣지 않아도 됨.
--> vector 컨테이너와 같은 대규모 리소스를 반환하는 함수 작성 가능.
Q. std::move 함수가 수행하는 일은?
A. 파라미터를 "무조건" Rvalue Reference로 타입 캐스팅
--> 절대 이름에 낚이면 안된다.
std::move 호출만으로는 아무것도 아동시키지 않는다.
std::move 함수는
Lvalue를 Rvalue로 취급하고 싶을 떄 사용한다.
(컴파일러에게 해당 객체가 이동해도 무관한 객체임을 알려주기 위해서)
1. void foo(string&& param);
2. string&& var = string();
3. auto&& var2 = var1;
4. template<typename T>
void foo(T&& param);
위에서 R-value 를 찾아보자.
답은 1,2 번이다.
&& 참조자가 템플릿 함수의 템플릿 파라미터 또는 auto 타입과 함께 사용되었을 경우
Universal Reference 라고 한다.
(R-value 아님!!!!)
Universal Reference 란?
- Lvalue와 Rvalue를 모두 참조할 수 있는 포괄적 (Universal) 레퍼런스
- 반드시 Rvalue Reference와 구분되어야함
- Perfect Forwarding 구현을 위한 열쇠
Old C++ 에서는 해결할 수 없는 문제가 하나 있었는데,
그건 바로 Forwading Problem 이었다.
- make_shared 함수와 같은 factory 함수 작성
template<typename T, typename Arg>
T* factory(arg& arg)
{
return new T(arg);
}
struct Y
{
Y(const int& n) {}
};
--> 결국 non-const 와 구분하며 모두 명시해 주어야함.
- 작성해야 하는 함수의 개수가 2^n 으로 증가한다. (n=파라미터 갯수)
- 가변인자는 말할 것도 없음.
따라서 universal 이 필요함.
int n = 0;
x* px = factory<X>(n);
y* px = factory<Y>(10);
이렇게 짧게 줄일 수 있다.
'스터디 > C++' 카테고리의 다른 글
2진수 표현 방법, 구분자 ' 지원 (0) | 2015.05.13 |
---|---|
auto,decltype,nullptr,std:array (0) | 2015.05.07 |
for문 한개와 두개의 성능차이. (0) | 2015.02.25 |
C++ 손건의 흑역사 (재미있는 C++ 문제) (0) | 2015.02.25 |
C++ 에서 Reflection 을 지원하지 않는 이유 (0) | 2015.02.25 |