2014-10-12 4 views
0

Рассмотрите приведенный ниже код C++ 11. Если я правильно понимаю семантику перемещения, конструктор копирования не следует вызывать. Но это. Может кто-нибудь объяснить, почему?C++ 11: Почему здесь вызывается копия ctor?

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" 
} 
+0

Вы явно объявили копию ctor для 'traced', поэтому у нее нет движка ctor. –

+0

Ну, почему это работает в случае emplace_back? Не следует ли вызывать копию трассировки ctor даже в этом случае? – user855

+0

emplace_back использует конструктор по умолчанию. Он не копирует, это точка emplace_back. –

ответ

5
aList.push_back(A(6)); 

Это создает временную 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 Вы должны использовать очень нечетную версию gcc, если 'emplace_back' имеет эту подпись. –

+0

@TC; http://i.imgur.com/POotrLp.png Я проверил Visual Studio 2013. То же самое. У них обоих такое. Я думаю, что это не «точная» же «подпись», как «emplace_back» .. но она использует 'emplace_back'. Это может быть одна и та же подпись. – Brandon

Смежные вопросы