다음 링크를 통해 공부하자.

모두의 코드 사이트가 그나마 가장 보기 쉬운 것 같다.

 

www.learncpp.com/cpp-tutorial/rvalue-references/

www.learncpp.com/cpp-tutorial/move-constructors-and-move-assignment/

 

 

blog.naver.com/devmachine/178065606 ([C++11] Rvalue Reference #2 - Move Semantics )

 

[C++11] Rvalue Reference 강좌 모음

C++11 Rvalue Reference 강좌 모음 제 블로그에 포스팅했던 Rvalue Reference 강좌의 링크를 보기 쉽...

blog.naver.com

 

https://modoocode.com/228

 

씹어먹는 C++ - <12 - 2. Move 문법 (std::move semantics) 과 완벽한 전달 (perfect forwarding)>

 

modoocode.com

 

(좀 옛날 글인데, modoocode.com/189)

 

문자열과 그 길이 정보를 담고 있는 MyString 클래스 (= std::string) 예시를 보자 (위 모두의코드 링크)

 

복사 생성자 vs 이동 생성자
MyString::MyString(const MyString &str)
다른 Mystring str(lvalue) 받아서, 그 길이만큼 메모리 할당 후 character 일일히 똑같이 붙여넣기

MyString::MyString(MyString &&str)
똑같이 다른 Mystring str(rvalue) 받되,
str의 포인터, 사이즈, 메모리 할당량 정보 등을 assignment =로 그대로 옮기기만 함 (복사X)


assignment = 를 통한 복사 vs 이동
위와 비슷.
복사는 실제로 할당한 메모리에 정보 똑같이 붙여넣기 하고,
이동은 pointer나 기타 값들만 =로 옮겨줌

즉, 이동이 복사보다 훨씬 computationally efficient함.

move는 인자로 받은 lvalue를 rvalue로 바꿔주는 역할. 이름과 달리 뭔가를 move하지 않음
우측값 = move(좌측값)

 

 

Q. Rvalue reference는 왜 필요한거야? 어디 쓰이는건데?

얄팍하게 공부해본 바로는, '복사/대입 연산자 구현할때 불필요한 과정을 줄이려고 + parameter forwarding 해주는 wrapper 만들 때 다른 타입때문에 생기는 컴파일 오류를 잡아내려고' 정도인데, 아직 이게 쓸만한건지 잘 모르겠다

구글 검색

[16July21] 복사 연산자보다 훨씬 효율적인 '이동' 연산을 구현하고싶은데, 기존의 lvalue reference & 만 가지고는 input parameter가 rvalue인지 알 수 없어서 새롭게 도입함.

rvalue referece -> move semantic + parameter forwarding

 

 

* const T& 로 우측값 레퍼런스 받을 수 있다

그 이유는 const 레퍼런스 이기 때문에 임시로 존재하는 객체의 값을 참조만 할 뿐 이를 변경할 수 없기 때문입니다.

(가끔 코드짜면서 레퍼런스 앞에 const 해줘야 하는 에러 만나는데 이것 때문인 듯?)

 


R-value 가지고 놀아봄.

더보기
더보기

Q. R-value reference로 value 바꿀 수 있나? (이러라고 있는 기능이 아니지만, 'reference'를 통해 실제 값이 바뀌는지 궁금하다 

int&& a = 5; // type : int&&
cout << a << "\n";
a = 3;
cout << a;
/*
Output
5 3
*/

근데 이건 그냥 a 메모리 주소에 있는 값을 바꾼 것 아닌가?

좀 더 해보자. 

 

// 1차원 배열
vector<int> v(10);
iota(v.begin(), v.end(), 1);
cout << v << "\n"; // 벡터 출력 함수 따로 정의

int& refer = v[1]; // type : int&
// int&& refer = v[1]; // Syntax 에러
auto&& refer = v[1]; // type : int&

refer = 100;
cout << v << "\n";

/*
Output
[ 1 2 3 4 5 6 7 8 9 10 ]
[ 1 100 3 4 5 6 7 8 9 10 ]
*/
// 2차원 배열
vector<vector<int>> v(5, vector<int>(5, 2));
print::vec2d_print(v); cout << "\n"; // 2-D 벡터 출력 함수 따로 정의

int& refer = v[1][1]; // int &
// int&& refer = v[1][1]; // Syntax error
auto&& refer = v[1][1]; // int &

refer = 0;
print::vec2d_print(v);

/*
Output
2 2 2 2 2
2 2 2 2 2
2 2 2 2 2
2 2 2 2 2
2 2 2 2 2

2 2 2 2 2
2 0 2 2 2
2 2 2 2 2
2 2 2 2 2
2 2 2 2 2
*/

일반적인 값은 lvalue reference(&)로만 참조할 수 있다. Rvalue reference(&&)는 syntax 오류가 난다.

또 신기한 점은, auto&&를 쓰면 자동으로 lvalue reference가 된다는 점이다.

 

그런데, 한 가지 신기한 점을 발견했다. 바로  vector<bool>이다.

bool&은 아예 안되고, bool&& 과 auto&&가 되는데,

신기하게도 bool&&로 참조한 것은 값을 변경해도 실제 벡터 원소가 변경되지 않는다.

// 2차원 배열; vector<bool>
vector<vector<bool>> v(5, vector<bool>(5, false));
print::vec2d_print(v); cout << "\n"; // 2-D 벡터 출력 함수 따로 정의

//bool& refer = v[1][1]; // 비const 참조에 대한 초기 값은 lvalue여야 합니다.
bool&& refer = v[1][1]; // bool&&, 그러나 v[1][1]의 값을 바꾸지 못함
auto&& refer = v[1][1]; // std::_Vb_reference<std::_Wrap_alloc<std::allocator<unsigned int>>> &&

refer = true;
print::vec2d_print(v);

/*
Output (auto&&에 대해서만)
0 0 0 0 0 
0 0 0 0 0 
0 0 0 0 0 
0 0 0 0 0 
0 0 0 0 0 

0 0 0 0 0 
0 1 0 0 0 
0 0 0 0 0 
0 0 0 0 0 
0 0 0 0 0 
*/

 

찾아보니까 vector<bool>은 조금 다르다고 하다.

stackoverflow.com/questions/8399417/why-vectorboolreference-doesnt-return-reference-to-bool

'<언어> > [C++]' 카테고리의 다른 글

[Modern C++][C++11] nullptr  (0) 2021.05.11
[C++] Class 공부 & instantiation (+ Struct)  (0) 2021.03.24
[C++] Operator overloading (연산자 오버로딩)  (0) 2021.02.08
[C++] Type Conversion 정리  (0) 2020.12.07
[C++] sorting  (0) 2020.12.06

+ Recent posts