Upload
lusain-kim
View
485
Download
0
Embed Size (px)
Citation preview
INDEX
▪ C++에서의 Value Type▪ L-Value
▪ L-Value Reference &
▪ R-Value
▪ R-Value Reference &&
▪ 이동의미론▪ 이동의미론
▪ 사용 방법
▪ 사용 예
▪ 함정
▪ noexcept
▪ 템플릿에서의 사용▪ 템플릿에서의 &&
▪ 보편 참조(Universal Reference)
▪ std::forward
C++ Value Type
MSDN : https://msdn.microsoft.com/ko-kr/library/f90831hc.aspx
▪ 명칭의 유래는 대개 왼쪽에 위치할 수 있는 값이기 때문– 정확한정의는아님 !
▪ 단일 식을 넘어 지속되는 값
▪ 이름이 있는 모든 변수는 L-Value
ex)
int a; // a is L-value
char* str = “hello, world!”; // str is L-value
auto ret = Func(a); // ret is L-value
L-Value
▪ 복사되지 않으며 원본을 전달하는 참조
▪ 용도1. 변수에 다른 이름을 붙이고 싶을 때
2. 원본이 존재하는 것을 명시하며 복사하지 않고 매개 인자로 넘길 때
▪ 포인터와의 차이점1. 포인터는 초기화를생략하거나중간에 다른 포인터로값변경이가능
2. L-value는 생성시초기화하여야만 하고, 다른 L-value를 대입할수없음
▪ 참고– MSDN | https://msdn.microsoft.com/ko-kr/library/w7049scy.aspx
L-Value Reference &
▪ 사용법– 변수 선언 시 & 기호를 추가
– 초기화할 인자에는 별도의 기호가붙지 않음
ex)
int a = 15; // a is L-value
int& b = a; // b is L-value reference
b = 5; // assign 5 to b
cout << a; // a is 5
L-Value Reference &
▪ 명칭의 유래는 오른쪽에만 위치할 수 있는 값이기 때문– 정확한정의는아님 !
▪ 유지되지 않는 값– 숫자, 이름이없는문자열, 함수의반환값등
ex)
int a = 5; // 5 is Number. R-value
char* str = “hello, world!”; // “hello, world!” is String. R-value
auto ret = Func(a); // Func(a) is Return Value. R-value
R-Value
▪ L-Value 참조와의구분을위해나타난참조
▪ 참조를통한매개인자의전달에서원본의유지가필요없을때사용
▪ 사용자가구현했을경우이동연산이가능해짐
▪ 용도1. 의미체계이동의구현을 위하여
2. 소유권의 유일성을 보장하기 위하여 : unique_ptr
▪ 참고– MSDN | https://msdn.microsoft.com/ko-kr/library/dd293668.aspx
R-Value Reference &&
▪ 사용법– 변수 선언 시 && 기호를 추가
– L-Value와동일하게 정의 시점에 초기화되어야함
▪ 주의사항– 이름이 있는 변수이기 때문에 R-Value Reference는 L-Value
▪ 예제– 추후 설명
R-Value Reference &&
Q다음예제에서 L-Value와 R-Value를구분해보시오
…
int x = 3;
const int y = x;
int z = x + y;
int *p = &x;
cout << string{ "hello" };
++x;
x++;
중간 Quiz
Q다음예제에서 L-Value와 R-Value를구분해보시오
…
int x = 3;
const int y = x;
int z = x + y;
int *p = &x;
cout << string{ "hello" };
++x;
x++;
중간 Quiz
move semantics
MSDN : https://msdn.microsoft.com/ko-kr/library/dd293665.aspx
▪ C++11부터 R-Value Reference를 사용 가능– 이를 통해 R-Value를사용한 연산 가능
▪ R-Value는 임시 값이므로 원본을 그대로 사용해도 괜찮지 않을까?– 원본을 보존하지 않아도 되기때문에 의미체계이동을한다고표현(MSDN)
▪ 기본 자료형(Primitive Type) 은 이동하지않음
이동의미론
▪ R-Value가 아닌데 R-Value로 넘기고 싶은 경우– std::move()함수를 사용
▪ std::move– 인자를 R-Value로형변환시킨다
– 함수이름에속으면안된다. 이함수는이동을보장하지않는다
template<class _Ty>
constexpr remove_reference_t<_Ty>&&
move(_Ty&& _Arg) noexcept
{ // forward _Arg as movable
return (static_cast<remove_reference_t<_Ty>&&>(_Arg));
}
사용방법
▪ STL Container에서원소의삽입은이동연산을지원
class Unit; // 이동 연산을 지원하는 클래스
Unit A;
std::vector<Unit> v;
v.push_back(std::move(A)); // A를 vector에 이동하여 삽입
사용 예
▪ STL Container에서의이동연산은조건이까다로움
class Unit; // 이동 연산을 지원하는 클래스
Unit A;
std::vector<Unit> v;
v.push_back(std::move(A)); // A를 vector에 이동하여 삽입하지 않을 것이다
함정
▪ 이동연산중오류가발생한다면?
▪ 이동연산은예외발생시 rollback이불가능할위험존재– 원본을 보존하지 않기 때문에
– 이 때 예외가 발생하지 않는다는 것을 명시할 필요가 있음
▪ 함수의 뒤에 noexcept 키워드를 붙임으로써컴파일러에게 예외를 발생시키지 않음을 명시– 예외가 발생할 경우, 프로그램이 그냥 종료된다. 중대한 버그의 여지가 되므로 주의할 것.
▪ STL은 모든 이동 연산에 대해 noexcept를 요구– noexcept가 없으면 복사 연산을 호출하도록 구현 move_if_noexcept
noexcept참고 | http://mug896.blog.me/140167721658
At Template
MSDN : https://msdn.microsoft.com/ko-kr/library/dd293668.aspx
▪ 템플릿에서는 &&에 L-Value가올수도, R-Value가올수도있음> 템플릿에서 &는 L-Value Reference
▪ 이를보편참조(Universal Reference)라고함– 같은의미로 forward Reference가쓰임
▪ 보편참조가생긴이유– 템플릿에인자가많아질수록
L-Value Ref와 R-Value Ref가섞여쓰일경우의수가기하급수적으로늘어남
– 이를막고자둘모두혼용가능한보편참조가제안됨
Universal Reference
▪ 보편참조가생긴이유– 가변인자템플릿(Variadic Template)에서는인자의완벽전달이불가능
template<class Ty, class Args...>
void func(Ty&& arg, Args&& ...args)
{
// arg의 참조 형식을 알 수 없음
// Universal Reference를 통해 확인
// 어떻게…?
}
Universal Reference
▪ Universal Reference인자를다시매개인자로전달할때이인자가 R-Value인지, L-Value인지확인하기어려움
▪ 표준에서구현된함수존재 : std::forward– 완벽한전달을위한함수
▪ 인자의참조형식이 L-Value든 R-Value든원래참조형식대로 전달
▪ std::move와다른점– std::move는무조건 R-Value Ref로전달
– std::forward는원래 R-Value Ref였던인자만그렇게넘김
std::forward
▪ std::forward를사용하는예
template<class Ty, class Args...>
void func(Ty&& arg, Args&& ...args)
{
// process : arg를 처리하는 어떤 함수
process(std::forward<Ty>(arg));
// 재귀로 다른 인자도 처리할 수 있도록 처리
func(std::forward<Args>(args)...);
}
std::forward
▪ Rvalue Reference and constexpr –김경진– https://mva.microsoft.com/ko/training-courses/-with-c-korea-c--10300?l=8F8JAKd6_7904984382
▪ MSDN– 참조 | https://msdn.microsoft.com/ko-kr/library/dz43scw4.aspx
▪ Effective Modern C++ - Scott Meyers– http://www.aladin.co.kr/shop/wproduct.aspx?ItemId=66541334
▪
참고 자료