2012-04-20 3 views
5

이동 의미를 이해하기 위해 다음 코드를 작성했습니다. g ++ - 4.6에서는 예상대로 작동하지만 (예 : 복사본이없고 이동 만) g ++ - 4.7.0에서는 작동하지 않습니다. 나는 그것이 g ++에서 링크하는 버그라고 생각했다 - 4.7.0 그러나이 link은 g ++ - 4.7의 버그는 아니라고 말했다. 그래서, 위의 링크에서 이해할 수 있듯이, 나는 이동 생성자를 만들지 않았지만 여전히 복사 만합니다. 그러나 복사 생성자를 nothrow로 만들면 이동 만 수행됩니다. 아무도 이것을 설명 할 수 있습니까?vector, move semantics, nothrow and g ++ 4.7

#include <iostream> 
#include <vector> 
using namespace std; 

struct S{ 
int v; 
static int ccount, mcount; 
S(){} 
    //no throw constructor 
    //S(nothrow)(const S & x){ 
S(const S & x){ 
    v = x.v; 
    S::ccount++; 
} 
S(S&& x){ 
    v = x.v; 
    S::mcount++; 
} 
}; 

int S::ccount = 0; 
int S::mcount = 0; 
int main(){ 

vector<S> v; 
S s; 

for(int i = 0; i < 10; i++) { 
    v.push_back(std::move(s)); 
} 

cout << "no of moves = " << s.mcount << endl; 
cout << "no of copies = " << s.ccount << endl; 
return 0; 
} 

답변

5

어떻게 "이동 생성자를 사용하지 않습니까?" g ++ 4.7에서 이동 생성자에 noexcept으로 주석을 추가하면 예제는 이동 만합니다.

S(S&& x) noexcept{ ... } 

no of moves = 25 
no of copies = 0 
+0

감사합니다. 나는 그것을'S (nothrow) (S && ​​x) {....}'로 썼다. 그러나이 두 가지 "nothrow"버전의 차이는 무엇입니까? – suresh

+1

'noexcept'는 무언가를 던지지 않는 것으로 표시하는 C++ 11 키워드입니다. 사용한 서명은'nothrow'라는 함수를 선언합니다.이 함수는 rvalue ref로 'S'를 취해 값으로 'S'를 반환합니다. –

+0

그래서 복사 생성자를 이런 방식으로 표시하면 g ++ 4.7에서 move 생성자를 사용하게됩니다. g ++ 4.7은 "don '을 따르므로 클래스에 더 이상 ** 클래스가 없습니다 **하지만 복사 생성자가 있습니다 (그러나'nothrow'라고하는 함수) 이동 생성자 "규칙이 있으면 복사 생성자를 암시 적으로 생성하므로'std :: vector'는 이동 생성자를 사용해야합니다. –