Это мое понимание, что цель 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"'s 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 &)'
Обратите внимание, что компилятор попытался создать (и использовать) КОПИРОВАННЫЙ КОНСТРУКТОР. Как я уже говорил выше, я понимаю, что цель от emplace_back()
составляет , избегая использования конструктора копирования.
Конечно, так как компилятор пытается создать и вызвать конструктор копию, нет никакого способа, код компилируется даже если я определил конструктор копирования для stuff
, потому что std::unique_ptr
не может быть использована в копии конструктор. Следовательно, я очень хотел бы избежать использования конструктора копирования (на самом деле, мне нужно его избегать).
(Это VS 11.0.60610.01 Update 3 на Windows 7 64-разрядная версия)
Почему производящая компилятор, и пытается использовать, конструктор копирования, даже если я звоню emplace_back()
?
Примечание (в ответ на @ ответ Yakk в):
Явное добавив конструктор перемещения, следующим образом, решает проблему:
stuff(stuff && rhs)
: dummy_ptr(std::move(rhs.dummy_ptr))
, dummy_path(rhs.dummy_path)
{}
@ dannissenbaum Обратите внимание, что перемещение/копирование не вызывается в вашем случае, но должно существовать для случая, когда в векторе уже есть контент, и ему необходимо изменить размер. Экземпляр времени выполнения метода не знает, что он вызывается на пустой 'vector', поэтому он должен обрабатывать все пути кода. – Yakk