람다식
람다식은 함수객체를 따로 선언하지 않고 바로 생성할 수 있게 해주는 문법이다.
auto iter = find_if(vecInt.begin(), vecInt.end(), [](int n)->bool { return (n % 2 != 0);});
벡터를 순회하며 홀수인 iterator을 반환하는 코드이다.
[](int iTemp = 20) {cout << iTemp << endl; };//선언
[](int iTemp = 20) {cout << iTemp << endl; }();//선언 후 실행
int iResult = [](int iTemp, int iSrc)->int { return iTemp + iSrc; }(10, 20);
[]는 람다식이라는 것을 알리는 캡처절, 그 후 ()안에는 매개변수를 작성한다. {}는 함수 몸체와 같은 역할을 한다.
첫번째 줄은 람다식의 선언이고, 바로 실행시키고 싶다면 둘째 줄 처럼 괄호를 쳐서 바로 실행시킬 수 있다.
반환하는 자료형을 밝히지 않으면 묵시적으로 컴파일러가 반환 자료형을 판단하는데, 명시적으로 알리고 싶다면
세번째 줄처럼 () 뒤에 ->를 이용해 반환 자료형을 밝힐 수 있다.
int a = 3;
[=](){a+=5;}();
cout << a; //3
[&](){a+=5;}();
cout << a; //8
캡처절에는 외부 변수를 레퍼런스로 받을지 값으로 받을지 정할 수 있다. 값으로 받는다면 복사해서 외부 변수에 값을 더해도 적용되지 않고 레퍼런스로 받으면 외부 변수의 값을 수정할 수 있다.


R-value Reference
const int& r1 = 10; //읽기만 가능
int iTemp = 10;
int&& rR = 999; //우변값 참조 가능
int&& rR2 = iTemp; //(x) 좌변값 참조 불가
rR = iTemp;//좌변값 대입 가능
일반적인 레퍼런스는 좌변값만 가능하지만 우변값을 가리키는 레퍼런스도 생겼다.
먼저 레퍼런스에 const를 붙이면 우변값도 참조가 가능하다. 하지만 읽기만 가능하다.
&&를 사용하면 우변값 레퍼런스를 선언할 수 있다. const를 붙이는 것과 달리 좌변값, 우변값을
대입해 가리키는 우변 값을 바꿀 수 있다. 하지만 처음부터 좌변값을 참조하는 것은 불가능하다.
이동 생성자
객체를 복사하는 대신 소유권을 이동시켜 프로그램의 속도를 올리는 효과가 있다.
// 복사 생성자
CObj(const CObj& rhs)
: m_pArray(new int[rhs.m_iSize]), m_iSize(rhs.m_iSize)
{
memcpy(m_pArray, rhs.m_pArray, sizeof(int) * m_iSize);
}
// 이동 생성자
CObj(CObj&& rvr)
{
m_pArray = rvr.m_pArray;
m_iSize = rvr.m_iSize;
rvr.m_pArray = nullptr; // 이동 후, 소유권 이전
}
CObj라는 클래스가 있고 멤버로 m_pArray라는 동적 배열이 있다고 하자.
CObj를 복사하기 위해서는 m_pArray의 깊은 복사를 위해 새로운 공간을 할당해야 할 것이고 m_pArray의 크기가 클수록
복사 생성은 느려질 것이다. 그래서 복사 생성이 필요하지 않을 때 소유권만 이전하는 것이 이동 생성자이다. 소유권을
이전할 객체를 rvalue reference로 받고 m_pArray의 주소만 대입해주고 이전 객체의 m_pArray를 nullptr로 설정해 이전당한 객체의m_pArray 소유권을 박탈한다.
CObj Array;
CObj MoveCon(std::move(Array));
main함수에서는 std::move를 사용해 Array객체를 rvalue로 캐스팅한다. 이러면 Array의 동적 배열 m_pArray의 소유권은 MoveCon에게 넘어갔다. 이동생성자를 이용하면 힙에 메모리를 할당하는 연산이 일어나지 않기 때문에 속도가 훨씬 빠르다. 이렇게 객체의 소유권을 이전하는 것을 무브 시맨틱이라고 부른다.
'Today I Learned' 카테고리의 다른 글
| 23. 05. 12 - CBase 클래스, 소멸자 vs 함수, 라이브러리 만들고 적용 (0) | 2023.05.12 |
|---|---|
| 23. 05. 11 - 프로젝트 파일 디렉터리 설정, 클래스 get/set 함수 지양 (0) | 2023.05.11 |
| 23.02.28 - map (0) | 2023.02.28 |
| 23.02.24 - 반복자, 알고리즘 (0) | 2023.02.24 |
| 23.02.23 - cout, 벡터 (0) | 2023.02.24 |