据我了解,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()
的目的是避免使用复制构造函数。
当然,由于编译器正在尝试创建并调用 copy 构造函数,因此即使我为{{}定义了复制构造函数,代码也无法编译 1}},因为stuff
不能在复制构造函数中使用。因此,我非常希望避免使用复制构造函数(事实上,我需要避免使用它)。
(这是Windows 7 64位上的VS 11.0.60610.01 Update 3)
为什么编译器会生成并尝试使用复制构造函数,即使我正在调用std::unique_ptr
?
注意(回应@ Yakk的回答):
显式添加移动构造函数,如下所示,解决了问题:
emplace_back()
答案 0 :(得分:19)
Visual Studio 2013及更早版本无法为您编写默认移动构造函数。将一个简单的显式移动构造函数添加到stuff
。
如果需要重新分配,推送或安装后退会导致移动内容,在您的情况下,副本会移动,因为stuff
没有移动。
这是一个msvc错误。