C++오른쪽 값 참조
C++에서 상수,변수 또는 표현 식 은 왼쪽 값(lvalue)이나 오른쪽 값(rvalue)이 어야 합 니 다.
왼쪽 값:임시 적 이지 않 습 니 다.등호 의 왼쪽 이나 오른쪽 에 나타 날 수 있다.비상 왼쪽 값 과 상수 왼쪽 값 으로 나 눌 수 있다.
오른쪽 값:임시(이름 을 구하 지 않 고 현재 구문 에서 만 유효 하 며 주 소 를 찾 을 수 없습니다).등호 오른쪽 에 만 나타 날 수 있 습 니 다.비상 량 오른쪽 값 과 상수 오른쪽 값 으로 나 눌 수 있다.
왼쪽 값 참조:왼쪽 값 에 대한 인용 은 왼쪽 값 참조 입 니 다.비상 왼쪽 값 참조 와 상수 왼쪽 값 참조 로 나 눌 수 있 습 니 다.
주:상수 왼쪽 값 인용 은'만능'의 인용 유형 으로 모든 유형의 값 에 연결 할 수 있 습 니 다.비상 왼쪽 값,상수 왼쪽 값,비상 오른쪽 값 과 상수 오른쪽 값 을 포함 합 니 다.
오른쪽 값 참조(Rvalue References):오른쪽 값 에 대한 참조 가 오른쪽 값 참조 입 니 다.비상 량 오른쪽 값 인용 과 상수 오른쪽 값 인용 으로 나 눌 수 있다.
임시 대상 의 오른쪽 값 입 니 다.수명 주기 가 짧 습 니 다.일반적으로 현재 표현 식 을 실행 한 후에 방출 됩 니 다.
이 값 을 오른쪽 값 에 인용 함으로써 비 싼 복사 작업 을 하지 않 은 상태 에서'계속'되 어 생명 주기 가 오른쪽 값 참조 유형 변수의 생명 주기 와 똑 같이 길 게 할 수 있 습 니 다.
오른쪽 값 참조 의 두 가지 기본 특성:이동 의미(Move Semantics)와 완벽 한 퍼 가기(Perfect Forwarding)
이동 의미(Move Semantics)
자원 을 한 대상 에서 다른 대상 으로 옮 길 수 있 습 니 다.불필요 한 임시 대상 의 생 성,복사,폐 기 를 주로 해결 합 니 다.
이동 구조 함수 MyClass(Type&a):구조 함수 인자 가 오른쪽 값 일 때 복사 구조 함수 MyClass(const Type&a)가 아 닌 이동 구조 함 수 를 우선 사용 합 니 다.
이동 할당 연산 자 Type&operator=(Type&&a):할당 이 오른쪽 값 일 때 할당 연산 자 Type&operator=(const Type&a)를 복사 하지 않 고 이동 할당 을 우선 사용 합 니 다.
#include <iostream>
#include <string>
#include <utility>
struct MyClass
{
std::string s;
MyClass(const char* sz) : s(sz)
{
std::cout << "MyClass sz:" << sz << std::endl;
}
MyClass(const MyClass& o) : s(o.s)
{
std::cout << "copy construct!
";
}
MyClass(MyClass&& o) noexcept : s(std::move(o.s))
{
std::cout << "move construct!
";
}
MyClass& operator=(const MyClass& other) { // copy assign
std::cout << "copy assign!
";
s = other.s;
return *this;
}
MyClass& operator=(MyClass&& other) noexcept { // move assign
std::cout << "move assign!
";
s = std::move(other.s);
return *this;
}
static MyClass GetMyClassGo(const char* sz)
{
MyClass o(sz); // : NRVO
return o;
}
};
void func0(MyClass o)
{
std::cout << o.s.c_str() << std::endl;
}
void func1(MyClass& o)
{
std::cout << o.s.c_str() << std::endl;
}
void func2(const MyClass& o)
{
std::cout << o.s.c_str() << std::endl;
}
void func3(MyClass&& o)
{
std::cout << o.s.c_str() << std::endl;
}
int main(int arg, char* argv[])
{
MyClass a1("how");
MyClass a2("are");
a2 = a1; // copy assign :a1
a2 = MyClass("you"); // move assign :MyClass("you")
MyClass a3(a1); // copy construct :a1
MyClass&& a4 = MyClass::GetMyClassGo("go"); // move construct : MyClass::GetMyClassGo()
MyClass a5 = MyClass::GetMyClassGo("china"); // move construct : MyClass::GetMyClassGo() ; a5
MyClass a6("let");
MyClass a7("it");
MyClass a8("go");
MyClass a9("!");
func0(a6); // copy construct
func1(a7);
func2(a8);
//func3(a9); // error:
func0(MyClass::GetMyClassGo("god")); // move construct : MyClass::GetMyClassGo() ; foo0
//func1(MyClass::GetMyClassGo("is")); // error:
func2(MyClass::GetMyClassGo("girl")); // move construct : MyClass::GetMyClassGo()
func3(MyClass::GetMyClassGo("!")); // move construct : MyClass::GetMyClassGo()
return 0;
}
주:테스트 이상 코드 는 반드시 C++컴 파 일 러 최적화 기술 인 RVO,NRVO 와 복사 생략 을 닫 아야 합 니 다.std::move 를 사용 하여 이동 의 미 를 실현 합 니 다.
왼쪽 값 이나 오른쪽 값 을 오른쪽 값 참조 로 강제로 바 꿉 니 다.주:UE4 에서 MoveTemp 템 플 릿 함수 에 대응
std::move(en chs)는 아무것도 이동 하지 않 고 대상 의 상태 나 소유권 을 한 대상 에서 다른 대상 으로 이전 합 니 다.주:이동 만 할 뿐 메모리 의 이전 이나 메모리 복사 가 없습니다.
① 기본 유형(예 를 들 어 int,double 등)이 std::move 에 의 해 이동 한 후에 그 수 치 는 변화 가 없 을 것 이다.
② 복합 형식 이 std::move 로 이동 한 후 정의 되 지 않 았 지만 효과 적 인 상태(대부분의 구성원 함수 가 의미 가 있 음)예 를 들 어 표준 라 이브 러 리 의 용기 류 대상 이 이동 하면 빈 용기 가 됩 니 다.
완벽 한 퍼 가기(Perfect Forwarding)
템 플 릿 함수 에 대해 서 는 한 그룹의 매개 변 수 를 다른 함수 에 그대로 전달 할 수 있 습 니 다.
왼쪽 값,오른쪽 값,const 여부 가 변 하지 않 습 니 다.다음 과 같은 세 가지 장점 을 가 져 옵 니 다.
① 왼쪽,오른쪽 값 의 속성 확보
② 불필요 한 복사 작업 을 피한다.
③ 모드 함수 가 왼쪽 값,오른쪽 값,const 의 매개 변수 로 서로 다른 과부하 를 실현 하 는 지 피해 야 한다.
만능 참조(유 니 버 설 references,퍼 가기 참조)는 특수 한 템 플 릿 참조 유형 으로 오른쪽 값 참조 문법 형식 을 사용 합 니 다(그러나 오른쪽 값 참조 가 아 닙 니 다).예:template
T&t 는 자동 형식 추정 이 발생 할 때 미 정 참조 유형(유 니 버 설 references)입 니 다.T 는 들 어 오 는 매개 변수 t 가 오른쪽 값 인지 왼쪽 값 인지 에 달 려 있 습 니 다.오른쪽 값 은 T&&&를 거 쳐 오른쪽 값 으로 인용 되 고 왼쪽 값 은 T&&&를 거 쳐 왼쪽 값 으로 인용 된다.
std::move 는 전 능 인용 으로 이 루어 집 니 다.그 정 의 는 다음 과 같다.
template <typename T>
typename remove_reference<T>::type&& move(T&& t)
{
return static_cast<typename remove_reference<T>::type &&>(t);
}
/*****************************************
std::remove_reference
std::remove_reference<T &>::type ---> T
std::remove_reference<T &&>::type ---> T
std::remove_reference<T>::type ---> T
******************************************/
// ,
template <typename T> struct remove_reference{
typedef T type; // T type
};
// ,
template <class T> struct remove_reference<T&> //
{ typedef T type; }
template <class T> struct remove_reference<T&&> //
{ typedef T type; }
① t 가 왼쪽 값 일 때 U&move(U&t)로 펼 쳐 집 니 다.주:오른쪽 값 참조 유형 변수 도 왼쪽 값 입 니 다.② t 가 오른쪽 값 일 때 U&move(U&t)로 펼 쳐 집 니 다.
마지막 으로 static 을 통 해cast<>강제 형식 변환 을 진행 하여 오른쪽 값 참조 로 되 돌려 줍 니 다.주:static캐 스 트 가 유형 변환 을 사용 할 수 있 는 이 유 는 removereference:type 템 플 릿 은 T&,T&의 인용 을 제거 하고 구체 적 인 유형 T(템 플 릿 편 특 화)를 가 져 옵 니 다.
인용 접 기
법칙:왼쪽 값 인용 을 포함 하 는 것 은 왼쪽 값 인용 이 고,그렇지 않 으 면 오른쪽 값 인용 이다.
std::forward 를 사용 하여 매개 변수의 완벽 한 퍼 가기 를 실현 합 니 다.그 정 의 는 다음 과 같 습 니 다(en chs).
template <typename T>
T&& forward(remove_reference_t<T>& arg) // forward an lvalue as either an lvalue or an rvalue
{
return static_cast<T&&>(arg);
}
template <typename T>
T&& forward(remove_reference_t<T>&& arg) // forward an rvalue as an rvalue
{
static_assert(!is_lvalue_reference_v<T>, "bad forward call");
return static_cast<T&&>(arg);
}
마지막 으로 static 을 통 해cast<>인용 접 기 를 하고 형식 변환 을 강제 한 후 그대로 전송 파 라미 터 를 실현 합 니 다.주:UE4 에서 Forward 템 플 릿 함수 로 대응
void bar(int& a, int&& b)
{
int c = a + b;
}
void func(int a, int&& b)
{
int c = a + b;
}
template <typename A, typename B>
void foo(A&& a, B&& b) { // a, b
bar(std::forward<A>(a), std::forward<B>(b)); // std::forward , a,b
}
int main(int arg, char* argv[])
{
int a = 10;
foo(a, 20); // void foo(int& a, int&& b), std::forward , void bar(int& a, int&& b)
func(std::forward<int>(a), std::forward<int&&>(30)); // std::forward , void func(int a, int&& b)
return 0;
}
이상 은 C++오른쪽 값 참조 에 대한 상세 한 내용 입 니 다.C+오른쪽 값 참조 에 관 한 자 료 는 다른 관련 글 을 주목 하 십시오!이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
hdu 1717 소수 화 점수 2 (수학)소수 화 점수 2 레이 는 수학 시간 에 선생님 의 말씀 을 듣 고 모든 소수 가 점수 로 표시 되 는 형식 이 라 고 말 했다. 그 는 녹 기 시 작 했 고 곧 완성 되 었 다. 그러나 그 는 또 하나의 문 제 를...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.