- 등호의 왼쪽과 오른쪽 모두 놓일 수 있음.
- 메모리가 있어서 주소를 가짐.
- 이름이 있음.
- 단일 문장을 벗어나 외부에 참조가 가능함.
- 참조를 리턴하는 함수 : 호출 이후에 대입이 가능함.
- const 값 : 수정 불가능한 lvalue임.
- 등호의 오른쪽에만 놓일 수 있음.
- 메모리가 없어서 주소가 없음.
- 이름이 없음.
- 단일 문장에서만 사용가능함. : 세미콜론 만나면 사라짐.
- 값을 리턴하는 함수 : 임시객체, 정수/실수형 리터럴
- 상수는 아님
: 등호를 기준으로 해서 나누는 것이 아니라, 각각의 특징을 고려해서
lvalue인지 rValue인지를 구분하자.
: 상수 변수는 값을 수정할 수는 없지만, 메모리를 가지고 있기 때문에,
lvalue임.
-상수는 메모리가 없음.
: 임시객체인 rvalue에 상수 4를 넣을 수 없다.
Point().Set 함수를 호출해서 내부 데이터 값 변경이 가능함..
#include <iostream>
using namespace std;
int func1()
{
return 1;
}
int& func2()
{
int x = 2;
return x;
}
class Object
{
public :
Object() { cout << "constr" << endl; }
Object(const Object& other) { cout << "copy constr" << endl; }
~Object() { cout << "destru" << endl; }
};
Object& result()
{
Object a;
return a;
}
//=> 참조를 반환하는 것이지만, 실행 결과를 확인해보면,
// Object obj = result(); 여기서 복사본이 생기는 것을 확인할 수 있음
// 객체의 반환의 경우, 필수적으로 복사를 가지고 옴. : 임시 객체
// rValue는 상수가 아님.
int main()
{
int a = 5;
//func1() = 5;
func2() = 5;
// 임시객체 ? : 컴파일러에 의해 생성되는 객체로,
Object obj = result();
Object obj2;
result() = obj2;
cout << "end" << endl;
}
지역 객체를 반환한다는 것은 참조로 반환을 하든 값으로 반환을 하든,
임시객체를 생성함.
이런식으로 함수를 만들어야 함.
int &operator++(int&a)
{
a = a+ 1;
return a;
}
: Rvalue만 받을 수 있는 참조
여기로 가자.
5. 알아야 하는 부분
-> 결론은 const 참조의 모호성 때문이 결정적임.
1) const Ref는 lvalue도 받을 수 있고, rValue도 받을 수 있음. 모호하다.
-> rvalue를 받으면 상수성이 추가됨.
2) rvalue Ref는 rvalue만 받을수 있다.
이 때는 const Ref와 달리 상수성이 없다., 수정이 가능하다.
: move와 perfect Forwarding에서 사용함.
: 주소가 있는 값들만 가리킬 수 있음.
: rvalue와 lvalue 모두 참조 가능함.
: rvalue만 가리킬 수 있음.
1) lvalue의 경우, lvalue Ref > const lValue Ref
2) rValue의 경우, rValue Ref > const rValue Ref
현재 lValue와 rValue가 모두 있어서 lValue와 RValue 함수가 호출됨.
const Ref 함수만 남았을 때
- rvalur ref 타입의 변수는 lValue이다.
int &&n = 10;
10은 rValue이지만, 변수 n은 메모리가 있기 때문에, lValue에 속함.
결과 : 예상대로 lValue Ref 함수가 호출되는 것을 확인할 수 있음.
-> 즉 rvalue 변수는 대입 이후에 메모리를 가지고 있는 lvalue type 임.
rValue&&로 캐스팅을 하면, rValue Ref 함수가 호출되는 것을 확인할 수 있음.
: 물론 보편참조가 lValue , Rvalue 다 가져간다는 거는 알겠는데,
내가 직접 lvalue ,const lvalue , 보편 참조 만들면
그래도 보편 참조가 다 먼저 호출될까?
일단은 명시된 lvalue가 우선순위 높음.
템플릿 자체로만 확인해보자.
: T& 가 보편참조 보다 앞서다는 것을 확인할 수 있음.
이때는 const& 보다 보편참조가 앞섬
결론
: 어차피 보편참조는 rVAlue와 lValue 모두 받을 수 있고,
forward 를 통해서 완벽한 전달이 가능하므로, 가능한
보편참조를 이용해 템플릿 함수 작성하자.