这是我的理解,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
不能在副本中使用构造函数。因此,我非常想避免使用复制构造函数(事实上,我需要避免它)。
(这是VS 11.0.60610.01更新3在Windows 7 64位)
为什么编译器生成,并尝试使用,拷贝构造函数,即使我打电话emplace_back()
?
注(响应@ Yakk的答案):
明确加入移动构造函数,如下所示,可以解决该问题:
stuff(stuff && rhs)
: dummy_ptr(std::move(rhs.dummy_ptr))
, dummy_path(rhs.dummy_path)
{}
@dannissenbaum注意移动/复制不是在你的情况下调用,但必须存在的情况下,已经存在的内容在'vector'中,它需要调整大小。该方法的complie时间实例并不知道它在空的'vector'上被调用,所以它必须处理所有的代码路径。 – Yakk