Подтвердить что ты не робот

Почему конструктор копирования вызывается при вызове std::vector:: emplace_back()?

Я понимаю, что цель std::vector::emplace_back() заключается в том, чтобы избегать вызова конструктора копирования, а вместо этого для прямого создания объекта.

Рассмотрим следующий код:

#include <memory>
#include <vector>
#include <boost/filesystem.hpp>

using namespace std;

struct stuff
{
    unique_ptr<int> dummy_ptr;
    boost::filesystem::path dummy_path;
    stuff(unique_ptr<int> && dummy_ptr_,
          boost::filesystem::path const & dummy_path_)
        : dummy_ptr(std::move(dummy_ptr_))
        , dummy_path(dummy_path_)
    {}
};

int main(int argc, const char * argv[])
{

    vector<stuff> myvec;

    // Do not pass an object of type "stuff" to the "emplace_back()" function.
    // ... Instead, pass **arguments** that would be passed
    // ... to "stuff" constructor,
    // ... and expect the "stuff" object to be constructed directly in-place,
    // ... using the constructor that takes those arguments
    myvec.emplace_back(unique_ptr<int>(new int(12)), boost::filesystem::path());

}

По какой-то причине, несмотря на использование функции emplace_back(), этот код не скомпилируется с ошибкой:

error C2248: 'std::unique_ptr<_Ty>::unique_ptr' : cannot access private member declared in class 'std::unique_ptr<_Ty>' [...] This diagnostic occurred in the compiler generated function 'stuff::stuff(const stuff &)'

Обратите внимание, что компилятор попытался создать (и использовать) COPY CONSTRUCTOR. Как я уже говорил выше, я понимаю, что цель emplace_back() заключается в том, чтобы избежать использования конструктора копирования.

Конечно, поскольку компилятор пытается создать и вызвать конструктор копировать, то нет возможности компилировать код , даже если я определил конструктор копирования для stuff, потому что std::unique_ptr не может использоваться в конструкторе копирования. Следовательно, я очень хотел бы избежать использования конструктора копирования (на самом деле, мне нужно его избегать).

(Это VS 11.0.60610.01 Обновление 3 для Windows 7 64-бит)

Почему компилятор генерирует и пытается использовать конструктор копирования, хотя я звоню emplace_back()?


Примечание (в ответ на ответ @Yakk):

Явное добавление конструктора перемещения, как описано ниже, решает проблему:

stuff(stuff && rhs)
    : dummy_ptr(std::move(rhs.dummy_ptr))
    , dummy_path(rhs.dummy_path)
{}
4b9b3361

Ответ 1

Visual Studio 2013 и ранее не могут писать конструкторы по умолчанию для вас. Добавьте простой конструктор перемещения к stuff.

Нажатие или возврат обратно может привести к перемещению материала, если ему необходимо перераспределить, что в вашем случае копирует, поскольку stuff не имеет перемещения.

Это ошибка msvc.