이동 된 객체로 무엇을 할 수 있습니까?


138

표준은 객체가 이동 한 후에 할 수있는 것을 정확하게 정의합니까? 이동 된 객체로 할 수있는 모든 것은 그것을 파괴하는 것이라고 생각했지만 충분하지는 않습니다.

예를 들어 swap표준 라이브러리에 정의 된 함수 템플릿 을 사용하십시오.

template <typename T>
void swap(T& a, T& b)
{
    T c = std::move(a); // line 1
    a = std::move(b);   // line 2: assignment to moved-from object!
    b = std::move(c);   // line 3: assignment to moved-from object!
}

분명히 이동 된 객체에 할당 할 수 있어야합니다. 그렇지 않으면 2 행과 3 행이 실패합니다. 객체에서 이동하여 다른 작업을 수행 할 수 있습니까? 표준에서 이러한 세부 정보를 정확히 어디에서 찾을 수 있습니까?

(그런데, 왜 그 것이다 T c = std::move(a);대신에 T c(std::move(a));라인 1?)

답변:


53

이동 된 오브젝트는 지정되지 않았지만 유효한 상태로 존재합니다. 즉, 객체가 더 이상 많은 것을 수행 할 수는 없지만 모든 멤버 함수는 operator=정의 된 상태 (및 정의 된 상태의 모든 멤버 포함)를 포함한 정의 된 동작을 나타내야하며 여전히 파괴가 필요합니다. 표준은 각 UDT에 고유하기 때문에 특정 정의를 제공하지 않지만 표준 유형에 대한 사양을 찾을 수 있습니다. 컨테이너와 같은 컨테이너는 비교적 분명합니다. 컨텐츠를 옮기기 만하면 빈 컨테이너가 올바르게 정의 된 유효한 상태입니다. 프리미티브는 이동 한 오브젝트를 수정하지 않습니다.

참고 사항 : T c = std::move(a)이동 생성자 (또는 이동이 제공되지 않은 경우 복사 생성자)가 명시 적 인 경우 함수가 실패 할 것이라고 생각합니다.


26
모든 멤버 함수가 정의 된 동작을 나타내는 것은 아닙니다 . 전제 조건이없는 사람 만. 예를 들어 pop_back, 이동 출처를 원하지 않을 것입니다 vector. 그러나 그것이 사실인지 확실히 알 수 있습니다 empty().
Howard Hinnant

6
@Howard Hinnant : pop_back비어 있음 vector에서 메모리에서 pop_back정의되지 않은 동작이 있으므로 정의되지 않은 동작을 나타내는 이동 된 벡터에서 일관성이 있음 을 확신합니다 .
강아지

12
우리는 움직이는 물체에 대해 논의하고 있습니다. 빈 상태 인 것으로 알려진 개체가 아닙니다. 이동 된 객체는 지정되지 않은 상태입니다 (물론 달리 지정되지 않은 경우). [lib.types.movedfrom]
Howard Hinnant

5
@Howard 지정되지 않았지만 유효하므로 pop_back여전히 유효한 벡터에서와 같이 동작합니다 (빈 벡터 일 수도 있음).
Christian Rau

1
이 문맥에서 불특정하고 유효한 의미는 무엇입니까?
Ankur S

114

17.6.5.15 [lib.types.moved from]

C ++ 표준 라이브러리에 정의 된 유형의 객체는 (12.8)에서 이동할 수 있습니다. 이동 조작은 명시 적으로 지정되거나 내재적으로 생성 될 수 있습니다. 달리 명시되지 않는 한, 이동 된 객체는 유효하지만 지정되지 않은 상태에 놓입니다.

오브젝트가 지정되지 않은 상태 인 경우 전제 조건이없는 오브젝트에 대한 조작을 수행 할 수 있습니다. 수행하려는 전제 조건이있는 조작이있는 경우 오브젝트의 지정되지 않은 상태가 전제 조건을 만족하는지 알 수 없으므로 해당 조작을 직접 수행 할 수 없습니다.

일반적으로 전제 조건이없는 조작의 예 :

  • 파괴
  • 할당
  • 같은 const를 관찰자 get, empty,size

일반적으로 전제 조건이있는 조작의 예 :

  • 역 참조
  • pop_back

이 답변은 이제 비디오 형식으로 나타납니다 : http://www.youtube.com/watch?v=vLinb2fgkHk&t=47m10s


1
그러나 다른 객체와 마찬가지로 전제 조건을 간단히 확인할 수 있습니다.
fredoverflow

6
@FredOverflow 물론 이러한 검사 자체에는 전제 조건이없는 한.
Christian Rau

1
@Chris :하지만 객체에서 이동하지 않은 일반 객체와 어떻게 다른가요?
fredoverflow

2
별도의 질문을해야한다-수도 있지만, 평균 않습니다 : 내가 가진 문자열이있는 경우 char* buffer;int length;모두의 구성원, 다음 내 이동 생성자 / 할당해야 스왑 (또는 설정) 값? 아니면 길이가 지정되지 않은 있다면 확인, (의미가 될 것입니다 emptysize의미없는 값을 반환)?
UncleBens

3
@ 6502 : 말이되지 않습니다. 생성 된 경우 이동 ctor 표준을 위반하므로 C ++ 03 클래스는 "C ++ 0x 표준을 위반"하지 않습니다 . 그리고 C ++ 03 코드는 해당 클래스를 이동하지 않으므로 이동 ctor를 생성 할 이유가 없습니다.
MSalters
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.