2014-10-12 2 views
0

C++ 11을 실행하는 아래의 코드를 고려하십시오. move semantics가 올바르게 이해되면 복사 생성자를 호출하면 안됩니다. 하지만 그것은. 왜 누군가가 설명 할 수 있습니까?C++ 11 : 여기에 복사기가 호출되는 이유는 무엇입니까?

template<class D> 
struct traced 
{ 
public: 
    traced() = default; 
    traced(traced const&) { std::cout << typeid(D).name() << " copy ctor\n"; } 

protected: 
    ~traced() = default; 
}; 


class A : public traced<A>{ 
public: 
    A(int x) : x_(x) {} 
private: 
    int x_; 
}; 

int main() { 
    // I thought the following two are equivalent. Apparently not. 
    aList.push_back(A(6)); // Prints out ".. copy ctor" .. 
    aList.emplace_back(6); // Does not print out " ... copy ctor" 
} 
aList.push_back(A(6)); 
+0

'추적'에 대한 복사본 ctor를 명시 적으로 선언 했으므로 이동 코드가 없습니다. –

+0

음, 그럼 왜 emplace_back의 경우에 작동합니까? 이 경우에도 추적 코드를 호출하면 안됩니까? – user855

+0

emplace_back이 기본 생성자를 사용 중입니다. 그것은 복사하지 않습니다, 그것은 emplace_back의 포인트입니다. –

답변

5

이 임시 A를 구축 용기로 이동시킨다. 묵시적으로 생성 된 A의 이동 생성자가 호출되어 임시의 기본 하위 객체 인 traced<A>을 생성해야합니다. 그러나 trace은 명시 적으로 복사 생성자를 선언하므로 기본적으로 이동 생성자가 없으므로 A의 이동 생성자는 기본 클래스 하위 객체에 대한 복사를 수행해야합니다.

aList.emplace_back(6); 

이것은 컨테이너에 직접 A을 구성합니다. 어떠한 종류의 복사 나 이동도 필요하지 않습니다.

+0

: S 내 gcc는 push_back을'push_back (T && obj)'로 정의합니다 ..'emplace_back'과 똑같은 서명을가집니다. mingw-builds-64 사용 4.8.1 posix-threads seh. 그러나 좋은 설명. – Brandon

+0

@Brandon'emplace_back'이 그 서명을 가지고 있다면 gcc의 아주 이상한 버전을 사용해야합니다. –

+0

@TC; http://i.imgur.com/POotrLp.png Visual Studio 2013을 확인했습니다. 두 사람 모두 그렇게 생각합니다. 나는'emplace_back'과 똑같은 "똑같은"서명이 아닌 것 같지만'emplace_back'을 사용합니다. 같은 서명 일 수도 있습니다. – Brandon

관련 문제