为什么在对std::vector::template_back()的调用中调用了复制构造函数

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

本文关键字:调用 复制 构造函数 back std vector template 为什么      更新时间:2023-10-16

据我所知,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 &)'

请注意,编译器试图创建(并使用)COPY CONSTRUCTOR。正如我在上面所讨论的,我的理解是emplace_back()目的避免使用复制构造函数。

当然,由于编译器正试图创建并调用复制构造函数,因此即使我为stuff定义了复制构造函数,代码也无法编译,因为std::unique_ptr不能在复制构造函数中使用。因此,我非常希望避免使用复制构造函数(事实上,我需要避免它)。

(这是Windows 7 64位上的VS 11.0.60610.01更新3)

为什么编译器生成并试图使用复制构造函数,即使我正在调用emplace_back()


注(回应@Yakk的回答):

显式添加move构造函数,如下所示,解决了问题:

stuff(stuff && rhs)
    : dummy_ptr(std::move(rhs.dummy_ptr))
    , dummy_path(rhs.dummy_path)
{}
Visual Studio 2013及更早版本无法为您编写默认的移动构造函数。向stuff添加一个简单的显式移动构造函数。

如果需要重新分配,向后推送或放置可能会导致内容被移动,在您的情况下,这是复制的,因为stuff没有移动。

这是一个msvc错误。