为什么在对std::vector::template_back()的调用中调用了复制构造函数
Why is copy constructor called in call to 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 &)'
请注意,编译器试图创建(并使用)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)
{}
stuff
添加一个简单的显式移动构造函数。
如果需要重新分配,向后推送或放置可能会导致内容被移动,在您的情况下,这是复制的,因为stuff
没有移动。
这是一个msvc错误。
- 当从函数参数中的临时值调用复制构造函数时
- 为什么调用复制构造函数而不是移动构造函数?
- 为用户定义的类正确调用复制构造函数/赋值运算符
- 编译器调用复制运算符而不是移动运算符
- push_back std::vector,则重复调用复制构造函数
- 为什么调用复制构造函数来构造空unique_ptr向量?
- 为什么转换运算符调用复制构造函数两次,而等效函数只调用它一次
- 我打算调用initializer_list构造函数,如果存在,则事先调用复制构造函数:为什么?
- C++ - 从移动分配运算符调用复制分配
- 构造函数初始值设定项列表未调用复制构造函数
- 为什么在我的代码中调用复制构造函数而不是移动构造函数?
- std::map 在 [] 上调用默认构造函数,在 insert() 上调用复制构造函数
- 通过引用传递对象时是否调用复制构造函数?
- 如果函数按值传递并按值返回,将调用复制构造函数多少次
- 为什么要抛出引用调用复制构造函数的异常?
- 为什么即使参数标记为"const",也会调用复制构造函数?
- Clang-Tidy:移动构造函数通过调用复制构造函数来初始化类成员
- 为什么当我添加一个不同的对象(复制构造函数中的参数)时调用复制构造函数?
- 为什么调用复制构造函数,当我只返回对象 c++ 的引用时
- 为什么在下面的代码中调用复制构造函数两次