gpt4 book ai didi

c++ - 使用 unique_ptr move 语义

转载 作者:可可西里 更新时间:2023-11-01 15:49:18 27 4
gpt4 key购买 nike

我使用的是 Visual Studio 2012 Update 2,我无法理解为什么 std::vector 试图使用 unique_ptr 的复制构造函数。我看过类似的问题,大多数都与没有显式 move 构造函数和/或运算符有关。

如果我将成员变量更改为字符串,我可以验证是否调用了 move 构造函数;但是,尝试使用 unique_ptr 会导致编译错误:

error C2248: 'std::unique_ptr<_Ty>::unique_ptr' : cannot access private member declared in class 'std::unique_ptr<_Ty>' .

我希望有人能指出我所缺少的,谢谢!

#include <vector>
#include <string>
#include <memory>

class MyObject
{
public:
MyObject() : ptr(std::unique_ptr<int>(new int))
{
}

MyObject(MyObject&& other) : ptr(std::move(other.ptr))
{
}

MyObject& operator=(MyObject&& other)
{
ptr = std::move(other.ptr);
return *this;
}

private:
std::unique_ptr<int> ptr;
};

int main(int argc, char* argv[])
{
std::vector<MyObject> s;
for (int i = 0; i < 5; ++i)
{
MyObject o;
s.push_back(o);
}

return 0;
}

最佳答案

push_back() 函数按值获取其参数。因此,尝试复制构造 push_back() 的参数(如果您传递的是左值),或者尝试 move 构造它(如果您传递的是右值)。

在这种情况下,o 是一个左值 - 因为命名对象是左值 - 并且右值引用不能绑定(bind)到左值。因此,编译器无法调用您的 move 构造函数。

为了让你的对象 move ,你必须写:

s.push_back(std::move(o));
// ^^^^^^^^^

在这种情况下,令我感到惊讶的是,VC11 似乎隐式地为 MyObject 生成了一个复制构造函数,而没有将其定义为 deleted(根据您发布的错误判断)。这不应该是这种情况,因为您的类声明了一个 move 构造函数。根据 C++11 标准的第 12.8/7 段,事实上:

If the class definition does not explicitly declare a copy constructor, one is declared implicitly. If the class definition declares a move constructor or move assignment operator, the implicitly declared copy constructor is defined as deleted; otherwise, it is defined as defaulted (8.4)

我必须得出结论,虽然您得到的错误是正确的 - 因为您没有将右值传递给 push_back() - VC11 在这里并不完全兼容。

关于c++ - 使用 unique_ptr move 语义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16010630/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com