std::unique_ptr 在推送到 std::vector 时的正确用法是什么?
What is the correct usage of std::unique_ptr while pushing into std::vector
我想在我的类中有一个指向对象的指针向量。为了避免为它制作析构函数,我想使用 std::unique_ptr
,因为对象是在我的类中创建/拥有/销毁的,但我有一个无法理解的编译器错误。下一个代码将作为我问题的简短示例:
std::unique_ptr<int> createPtr(int value)
{
std::unique_ptr<int> ptr(new int(value));
return ptr;
};
int main()
{
std::vector<std::unique_ptr<int>> vec;
vec.push_back(createPtr(1));
std::unique_ptr<int> ptr = createPtr(2);
vec.push_back(ptr);//error C2248: 'std::unique_ptr<_Ty>::unique_ptr' : cannot access private member declared in class 'std::unique_ptr<_Ty>'
}
你能解释一下为什么我会收到这个错误以及std::unique_ptr
的正确用法是什么?
要么:
vec.push_back(std::move(ptr));
或:
vec.emplace_back(createPtr(2));
考虑vec.push_back()
。它有两个重载,需要const std::unique_ptr<int>&
或std::unique_ptr<int>&&
。第一次重载永远不能使用。这是因为vector<>
要求类型是可分配的或可移动的(C++11 加法)。"可分配性"意味着复制。 push_back(const T&)
将尝试将传入的值复制(分配)到容器末尾的新空间。 std::unique_ptr<>
表示由单个所有者拥有的资源。通过复制它(指针),将存在多个所有者。因此,unique_ptr
是不可复制的。
说了这么多,你只能使用T&&
重载。
createPtr()
返回std::unique_ptr<int>
,但由于这是一个临时结果(函数返回值),它被认为是一个右值引用(隐式)。这就是为什么可以使用它的原因。
ptr
只是一个std::unique_ptr<int>
,它是一个左值引用(无论你是否在它旁边加上&&,因为命名的右值仍然被视为左值)。左值永远不会隐式转换为右值(完全不安全)。但是你基本上可以通过使用 std::move()
告诉编译器"好的,你可以接受我传递给你的对象,我保证我不会期望参数保持不变"。
您有一个unique_ptr
:
std::unique_ptr<int> ptr = createPtr(2);
现在你把它的副本放在向量中:
vec.push_back(ptr);
现在,您有两个具有相同值的unique_ptr
。 如果允许这样做,它就不是唯一的。
- 如何找到"using namespace std"的违规用法?
- std::condition_variable 在 QThread::run() 中的用法
- std::conditional - 嵌套用法
- 我不理解 std::result_of 和 decltype 的这些用法
- std::forward 在参数传递中的用法是什么?
- std::decimal::decial64正确用法,g++4.6.3
- std::move()用法错误
- std::future的错误用法
- std::forward与std::move的用法
- std::vector<decltype(iter)>-decltype的有效用法
- std::map 的线程安全用法
- 继承自 std::函数、语法和用法
- std::remquo的目的和用法
- std::线程管理:用法和最佳实践
- 对"std::istreambuf_iterator"的用法感到困惑
- std::initializer_list的泛型类型用法
- 条件与 std::atomic <T>的基本用法
- 修改SFINAE习惯用法,使用std::is_athmetic检查函数的返回类型
- 派生类与基类的std::shared_ptr的用法
- 从 std::unique 返回的迭代器的用法