简体   繁体   English

为什么在调用std :: vector :: emplace_back()时调用复制构造函数?

[英]Why is copy constructor called in call to std::vector::emplace_back()?

It is my understanding that the purpose of std::vector::emplace_back() is specifically to avoid calling a copy constructor, and instead to construct the object directly. 我的理解是std::vector::emplace_back()的目的是专门避免调用复制构造函数,而是直接构造对象。

Consider the following code: 请考虑以下代码:

#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());

}

For some reason, despite the use of the emplace_back() function, this code fails to compile, with the error: 出于某种原因,尽管使用了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 &)'

Notice that the compiler attempted to create (and use) the COPY CONSTRUCTOR . 请注意,编译器尝试创建(和使用)COPY CONSTRUCTOR As I've discussed above, it's my understanding that the purpose of emplace_back() is to avoid the use of the copy constructor. 正如我上面所讨论的,我的理解是emplace_back()目的避免使用复制构造函数。

Of course, since the compiler is attempting to create and call the copy constructor, there's no way the code would compile even if I defined the copy constructor for stuff , because the std::unique_ptr cannot be used in a copy constructor. 当然,由于编译器试图创建并调用复制构造函数, 即使我为stuff定义了复制构造函数,代码也无法编译,因为std::unique_ptr不能在复制构造函数中使用。 Hence, I would very much like to avoid the use of a copy constructor (in fact, I need to avoid it). 因此,我非常希望避免使用复制构造函数(事实上,我需要避免使用它)。

(This is VS 11.0.60610.01 Update 3 on Windows 7 64-bit) (这是Windows 7 64位上的VS 11.0.60610.01 Update 3)

Why is the compiler generating, and attempting to use, the copy constructor, even though I am calling emplace_back() ? 为什么编译器会生成并尝试使用复制构造函数,即使我正在调用emplace_back()


Note (in response to @Yakk's answer): 注意(回应@ Yakk的回答):

Explicitly adding the move constructor, as follows, resolves the problem: 显式添加移动构造函数,如下所示,可以解决问题:

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

Visual Studio 2013 and earlier fails to write default move constructors for you. Visual Studio 2013及更早版本无法为您编写默认移动构造函数。 Add a simple explicit move constructor to stuff . 一个简单明确的移动构造函数添加到stuff

A push or emplace back can cause stuff to be moved if it needs to reallocate, which in your case copies, as stuff has no move. 如果需要重新分配,推送或安装后退可以导致移动东西,在你的情况下复制,因为stuff没有移动。

It is a msvc bug. 这是一个msvc错误。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM