微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何使用基于范围的for循环遍历std :: unique_ptr的std :: vector时获取对象的所有权?

如何解决如何使用基于范围的for循环遍历std :: unique_ptr的std :: vector时获取对象的所有权?

我有一个std::vector<std::unique_ptr<Kind>>,我想在对其进行迭代时对其进行清理,而无需显式调用其成员的析构函数.reset())。

Kind一个沉重的结构,其大小在迭代过程中会增加。下一个对象不需要了解以前的对象,因此我想在不需要它的同时清理iterand。

我知道向量最终会清除,但是到那时,大量Kind和它们动态分配的内存加起来了。我正在尝试将峰值内存减少到一个元素。

我想避免使用reset,因为其他开发人员可能不知道动态分配,请忘记在循环结束时调用reset并浪费内存。

我无法创建副本,

for(std::unique_ptr<Kind> t : store)

我无法像

那样移动它
for(std::unique_ptr<Kind> &&t : store)

那我该怎么办?

#include <iostream>
#include <vector>

struct Kind{
    char a;
    char *array;
    Kind(const char c): a(c)
    {
    }
    ~Kind(){
      free(array); // internal custom deallocator.
    }
};

int main() {
    std::vector<std::unique_ptr<Kind>> store;
    store.push_back(std::make_unique<Kind>('y'));
    store.push_back(std::make_unique<Kind>('z'));

    for(std::unique_ptr<Kind> &t : store){
        // increase size of Kind.array.
        std::cout << t->a;
        // Use the Kind.array
        // clean up t automatically.
    }
    return 0;

}

解决方法

将元素移出向量的示例。

int main() {
    std::vector<std::unique_ptr<Kind>> store;
    store.push_back(std::make_unique<Kind>('y'));
    for(std::unique_ptr<Kind> &t : store){
        auto tmp = std::move(t); // leaving a valid but empty entry in store
        std::cout << tmp->a;
        // clean up t automatically.
        // tmp runs out of scope and cleans up
    }
    return 0;
}

实际上与重置没有太大区别,但可能与您在实际程序中实际执行的操作有关。

,

如何使用基于范围的for循环在std :: unique_ptr的std :: vector上循环时获取对象的所有权?

使用对该元素的引用进行循环,并将std::move的唯一指针插入另一个元素。示例:

for(std::unique_ptr<Kind> &t : store){
    std::unique_ptr<Kind> owner = std::move(t);
    // do something with newly owned pointer

我要清理

无需保留较旧的结构

您可以通过重置指针来取消分配对象:

for(std::unique_ptr<Kind> &t : store) {
    // do something
    t.reset();

也就是说,这通常是不必要的。当向量超出范围时,它们将被自动销毁。

我正在尝试在此处保存一些内存

如果在迭代时分配动态对象,这可能会很有用。否则,它不会影响峰值内存使用。

,

如果您想确保实例在每次迭代后都立即删除,并且不能等到整个循环完成,则可以编写一个包装器来处理该情况并同时表达您的意图:

template <typename T>
struct Stealing {
  std::unique_ptr<T> ptr;
  Stealing(std::unique_ptr<T>& ptr) : ptr(std::move(ptr)) {
  }   
  auto operator*() {
    return ptr.operator*();
  }   
  auto operator->() {
    return ptr.operator->();
  }   
}

您可以在循环中使用它来替代unique_ptr,例如:

for (Stealing<Kind> t: store) {
  // do what you like with t as if it was a std::unique_ptr
  // when t goes out of scope,so does its member -> Kind gets destroyed
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?