2016-12-12 11 views
2

이 문제에 대해 한 번 더 말하지만 관련 질문은 내 질문에 대답하지 않습니다.이동 생성자가없는 개체 이동

표준은 매우 분명하다

12.8 복사 및 이동 클래스 개체,
§9
클래스 X의 정의가 명시 적으로 이동 생성자를 선언하지 않는 경우, 하나는 암시 적으로 선언됩니다
- X에 사용자 선언 된 복사 생성자가없는 경우
- X에 사용자가 선언 한 복사 할당 연산자가 없습니다.
- X에 사용자가 선언 한 MO가 없습니다.
- X에 사용자가 선언 한 소멸자가없고
- 이동 생성자가 암시 적으로 삭제됨으로 정의되지 않았습니다.
[참고 : 이동 생성자가 암시 적으로 선언되거나 명시 적으로 제공되지 않으면 이동 생성자를 호출 한 표현식이 대신 복사 생성자를 호출 할 수 있습니다. -

그래서 엔드 노트]의 마지막에 "참고"알았어 전에, 나는 컴파일을 실패 코드의 조각을 예상 (I는 알고 있지만, 그 복사에 해야 대체 이동) :

#include <iostream> 
using std::cout; 
class c 
{ 
public: 
    c() { cout << "c::c()\n"; } 
    c(std::initializer_list<int>) { cout << "c::c(std::initializer_list)\n"; }; 

    c(const c&) { cout << "c::c(const c&)\n"; } 
    c& operator=(const c&) { cout << "c& c::operator=(const c&)\n"; return *this; } 

    ~c() { cout << "c::~c()\n"; } 

    void f() {} 
}; 

void f(c&& cr) { cout << "f()\n"; cr.f(); } 

int main() 
{ 
    c x; 
    f(std::move(x)); 

    return 0; 
} 

그때 나는 마지막에 메모를했다,하지만 난 여전히 놀랐다 그 출력 위의 코드 :

C : C()
F()
c :: ~ c()

"누락 된"c::c(const c&)에 유의하십시오. 그런 다음 나는

c(c&&) = delete; 
c& operator=(c&&) = delete; 

을 추가했으며 결과는 여전히 동일합니다.

무엇이 여기에 있습니까?


$ g++ --version 
g++ (Ubuntu 5.4.0-6ubuntu1~16.04.2) 5.4.0 20160609 

컴파일러 플래그 : -s -O0 -march=native -pthread -std=c++11 -Wall -Wextra -DNDEBUG.

+4

'cr'은 r-value ** 레퍼런스 **입니다. 어떤 생성자도 아직 사용하지 않았습니다 ... –

+0

@ W.F. - 오, 내 답변을 게시하십시오. 너는 대단히 정확하다. (다 XX (표준 : : 이동 (x)는)'추가;'대신'F의 (c &&) 사용하는'예상 된 동작을 생산 –

+0

그것은 NOP 질문 XD – Stargateur

답변

6

예제의 매개 변수는 입니다. 여기서 참조 단어가 중요합니다.그것은 C++ 11이 게임에 들어가기 전에 어떤 생성자도 호출하지 않는다는 점에서 우리가 C++에서 알 수있는 평면 이전 레퍼런스와 다소 유사합니다 ... 당신이 전달하는 객체를 "가리키는 것"입니다. ..

는 이동 생성자를 호출 (또는 다른 교환을 수행) 우리는 상기 기준을 전달하는데 필요한 기준을 소비 예

void f(c&& cr) { 
    c cr2(std::move(cr)); 
} 
6

개체를 이동하지 않았습니다.

std::move은 실제로 아무 것도 움직이지 않기 때문에 실제로는 혼란 스럽습니다. 이동 생성자 또는 이동 지정 연산자 만이 객체를 이동할 수 있습니다. std::move은 r 값 참조 (&&)에 l 값 참조 (&)를 캐스팅합니다.

이동 생성자 또는 이동 할당 연산자는 r 값 참조 (&&)에 바인딩하여 객체 내용을 도용 할 수 있습니다.

+0

이 완벽하게 허용 대답을 보완 정말 좋은 설명입니다 +1가, 감사 –