#include <iostream>
#include <vector>
#include <list>
#include <deque>
#include <map>
#include <set>
#include<algorithm>
using namespace std;
// Modern C++ (C++11 부터 나온 아이들)
// 보편 참조(universal reference)
// 전달 참조(forwarding reference) C++17
// &&: &를 두 번 -> 오른값 참조 But 전달 참조 또한 같은 문법 사용
class Knight {
public:
Knight() { cout << "기본 생성자" << endl; }
Knight(const Knight&) { cout << "복사 생성자" << endl; }
Knight(Knight&&) noexcept { cout << "이동 생성자" << endl; }
};
void Test_RvalueRef(Knight&& k) // 오른값 참조
{
};
void Test_Copy(Knight k) {
}
// 전달 참조 or 오른값 참조
template<typename T>
void Test_ForwardingRef(T&& param) {
//왼값을 넣으면 왼값참조, 오른값을 넣으면 오른값 참조가 일어남
// TODO: 왼값 참조인지 오른값 참조인지 구분해야함
Test_Copy(forward<T>(param)); // forward를 통해 param이 오른값 참조인지 왼값 참조인지 확인후 변환 -> 왼값 참조라면 복사, 오른값 참조라면 이동
// 왼값 참조라면 복사
// 참조 받은 것은 오른값이지만 param 자체는 왼값의 성질을 갖는다.
// 따라서 TestCopy는 복사 생성자를 호출한다.
//Test_Copy(param);
// 오른값 참조라면 이동
//Test_Copy(move(param));
}
int main()
{
Knight k1;
//Test_RvalueRef(move(k1));
Test_ForwardingRef(move(k1));
Test_ForwardingRef(k1);
//auto&& k2 = k1;
//auto&& k3 = move(k1);
// 공통점 : 혐식 연역(type deduction)이 일어날 때 발생
// 전달 참조를 구별하는 법
//----------------------------------------------------
Knight& k4 = k1; // 왼값 참조
Knight&& k5 = move(k1); // 오른값 참조
// 오른 값 : 왼값이 아니다 = 단일식에서 벗어나면 사용 x한 얘들
// 오른 값 참조 : 오른값만 참좋할 수 있는 참조 타입
//Test_RvalueRef(k5); // k5의 타입은 오른값 참조값이 맞지만? 단일식을 벗어나도 사용 가능한 왼값의 성질을 갖는다
//Test_RvalueRef(move(k1));
return 0;
}