2013-05-25 5 views
1

나는 컴파일 오류를 추적했다이 방법으로 이동 의미를 사용할 수없는 이유는 무엇입니까? 이 두 주장 실패</p> <pre><code>struct Y { int&& y; Y(int&& y) : y(y) { } }; struct ZZ {}; struct Z { ZZ&& z; Z(ZZ&& z) : z(z) { } }; </code></pre> <p>을 : :이 경우에 왔을 때

exec.cpp: In constructor ‘Y::Y(int&&)’: 
exec.cpp:57:10: error: invalid initialization of reference of type ‘int&&’ from expression of type ‘int’ 
exec.cpp: In constructor ‘Z::Z(ZZ&&)’: 
exec.cpp:67:10: error: invalid initialization of reference of type ‘ZZ&&’ from expression of type ‘ZZ’ 

을하지만 정확히 왜 모르겠어요. 여기서 뭐가 잘못 됐니?

-std = gnu ++ 0x 옵션과 함께 g ++ 4.5.3을 사용하고 있지만 -std = C++ 0x 옵션에서도 발생합니다.

+3

회원으로 참조 값을 저장하는 것이 유용한 경우를 찾기가 힘듭니다. 문제의 배경에 대해 좀 더 자세히 설명해 주시겠습니까? –

+0

사실, 나는 단지 이동 의미론과 &&가 의미하는 것을 내 머리 속에서 생각하려고 노력하고있다. 나는 이유가 있는지 확실하지 않습니다. – Adrian

+0

업데이트 : 멤버로 r 값 참조를 사용하면 값이 거의없고 해당 멤버가있는 객체의 수명이 매우 길면 매우 위험 할 수 있다고 생각합니다. 약간의 가치가있을 수 있지만 매우 적게 보입니다. – Adrian

답변

2

무엇이든은 1-값입니다. 즉, 생성자 매개 변수 y은 이름이 "y"이므로 l 값 (r 값 참조 int)입니다.

std::move(y)을 사용하여 r 값으로 되돌립니다.

+0

아, 알겠습니다. 'int & i'는'i'가 명명 된 l- 값에 대한 참조이고'int && i'는'i'가 명명 된 r- 값에 대한 참조라는 것을 의미합니다. 그게 맞습니까? 하지만 'int && i'와 같은 것을 취하는 함수는 l 또는 r 값을 취할 수 있습니다. 나는 move semantics에 대한 더 많은 독해를해야 할 것입니다 .... – Adrian

+0

@Adrian'int & i'는'int' 타입의 l- 값에 대한 참조입니다. 'int && i'는'i'가'int' 타입의 r 값에 대한 참조임을 의미합니다. 두 경우 모두'i' ** 자체 **가 l 값입니다. 그리고, r 값 참조 ('&&')는 l 값에 바인드 할 수 없습니다. 또한 "명명 된 r 값"과 같은 것은 없습니다. 무언가가 이름을 가졌을 때 그것은 l-value입니다. – Angew

+0

@Angew :'int &'와'int &&'모두 * 참조입니다. 이 유형 중 하나의 변수의 id 표현식은 항상 'int'입니다. 차이점은 참조가 바인딩 할 수있는 값의 종류에 있습니다. –

2

당신은 : y(std::move(y))라고해야합니다. 그것은 rvalue 참조에 바인딩 할 수있는 표현식을 얻는 유일한 방법입니다. 벌거 벗은 식 y은 단지 lvalue입니다.

(이 점 참조 클래스 멤버에 대한 정확한 확인하는 것은 매우 위험하고 어려운합니다.) 이름이

+0

'std :: move '는 분명히 * normal * 방식이지만, 똑같이 확실히 유일한 방법은 아닙니다. 'std :: move'는 보통의 C++로 쓰여지고, [스스로 복제 할 수 있습니다] (http://stackoverflow.com/a/16745424/179910) (마음에, 그것은 단순한 static_cast 이상이 아닙니다). –

+1

@JerryCoffin : 예, 물론입니다. 'static_cast (x)'의 값은'T'가 비 참조 형이고 xvalue이므로 rvalue 참조에 바인드 할 수 있습니다. 나는 그 질문에 대한 답이 옳은 수준이라고 생각했다 :-) –

+0

그래, 나는 회원이 무언가에 대한 참조를 만들 때, 객체의 수명이 참조 된 객체의 수명보다 짧아야한다는 것을 알고있다. 그렇지 않으면 매달린 것과 같다. 포인터가 발생할 수 있습니다. – Adrian

관련 문제