2016-07-04 4 views
3

클래스 메소드와 필드에 나중에 액세스 :표준 :의 이동 *이 나는이 코드를 할 바보 같은 이해 ...하지만 이해를 위해, 다음을 고려하십시오

#include <iostream> 
#include <memory> 
#include <utility> 

struct S; 
void f(S && s); 

struct S { 
    S() : i{std::vector<int>(10, 42)} {} 
    std::vector<int> i; 
    void call_f() { f(std::move(*this)); } 
    void read() { std::cout << " from S: " << i.at(3) << std::endl; } 
}; 

void f(S && s) { std::cout << " from f: " << s.i.at(3) << std::endl; } 

int main() { 
    S s; 
    s.call_f(); 
    s.read(); 
} 

을 이 컴파일 및 g ++ 및 clang ++, 나는 std::vector<int> 이동할 것으로 예상되는 동안 실행합니다. gdb에서 이것을 실행하고 메모리를 보면 의 주소는 std::move 이후에 0으로 설정되지 않았지만, POD가 아닌 유형의 경우에는 0으로 설정됩니다. 따라서이 코드 조각에서 segfault가 예상됩니다.
누구든지이 동작을 설명해 주시겠습니까? s도 내부 필드도 무효화되지 않는 이유는 무엇입니까? this의 기능입니까?

+2

결코 세그 폴트를 "예상"하지 마십시오! 비록 당신이 (당신이하지 않은) 원인이 될 수있는 코드를 작성해도, 그 코드를 기대하는 것은 어리 석다. –

+0

std :: move (* this)는 아무 것도 움직이지 않으며, f의 이동 오버로드를 호출해도 괜찮음을 컴파일러에 알립니다. f의 이동 오버로드를 구현해도 s가 엉망이되지 않으면 인스턴스가 여전히 양호합니다. segfault를 원하면 f의 내부에서 s.i를 효과적으로 움직이는 무언가를 추가해야합니다. – rectummelancolique

+3

@rectummelancolique : 안녕하세요. 이것은 코멘트 섹션입니다. ↓↓↓↓↓ 답변을 게시판 게시판과는 별도로 SE Q & A를 설정하는 동료 검토 기능의 적용을받을 수 있도록 아래쪽에 놓으십시오. 감사! –

답변

5

std::move은 실제로 아무 값도 이동하지 않고 단지 으로 바뀌어이 움직일 수있게 허용합니다. (잘못된 이름의 비트이지만 지금은 붙어 있습니다.)

실제 이동 작업을 수행하려는 경우 범위에서 예외가 표시 될 가능성이 높습니다 (std::vector::at).

void f(S && s) { 
    S steal = std::move(s); 
    std::cout << " from f: " << s.i.at(3) << std::endl; 
} 

GCC 6.1이 나에게주는이

terminate called after throwing an instance of 'std::out_of_range' 
    what(): vector::_M_range_check: __n (which is 3) >= this->size() (which is 0) 
bash: line 7: 18043 Aborted     (core dumped) ./a.out 
+0

@LightnessRacesinOrbit 그 벡터는 10 개의 요소가 42로 초기화되어 있습니다. –

+0

@PiotrSkotnicki : Ahaha whoops –

+0

그리고 이것이'std :: move'가 "약간의 잘못된 이름"일뿐만 아니라 그것이하는 일에 대한 절대적으로 무시 무시한 이름 인 이유입니다. ! –

1

std::move 아무것도 움직이지 않는다 - 그것은 단지 이동의 ctor 또는 운영자를 이동되도록를 rvalue에 바인딩 할 수있는 동일한 개체를 referenceing가 xValue를 반환 = 호출 할 수 있습니다.

따라서 코드에서 이동은 수행되지 않습니다. f은 동일한 객체에 대한 rvalue 참조에서 작동합니다.

f 값으로 허용하는 경우 값이 이동하면 이동이 발생하며 i이 비어 있습니다.

+0

_ "예상 한 동작을 보게됩니다."_ 매우 그렇습니다. –

+0

충분히 공정하면 "움직이는 효과를 볼 수 있습니다."가 더 정확할 것입니다. –