从地图值中的unique_ptr迭代原始指针

Iterate raw pointers from unique_ptr in map values

本文关键字:ptr 迭代 原始 指针 unique 地图      更新时间:2023-10-16

我在地图值中使用unique_ptr。我需要将这些值作为原始指针的列表/向量获取。到目前为止,我已经做了如下工作。

#include <iostream>
#include <string>
#include <vector>
#include <memory>
#include <map>
class Foo {
  public:
    std::string val;
    Foo(std::string v) : val(v) {
    }
 };
 class Unique {
   public:
     std::map<int, std::unique_ptr<Foo>> unique_map;
     std::vector<Foo*> getFoos() {
       std::vector<Foo*> foos;
       for (auto& it : unique_map) {
         foos.push_back(it.second.get());
       }
       return foos;
     }
 };
 int main() {
   Unique unique;
   Foo* f1 = new Foo("1");
   Foo* f2 = new Foo("2");
   unique.unique_map.emplace(1, f1);
   unique.unique_map.emplace(2, f2);
   std::vector<Foo*> foos = unique.getFoos();
   for (Foo* foo : foos) {
     std::cout << foo->val;
   }
   std::cout<<"n";
   return 0;
 }

但这无法编译。最相关的错误消息似乎是

"/usr/include/c++/4.8/bits/stl_tree.h:140:49:注意:无法转换 'std::forward((* & __args#1))' (键入 'Foo*') 以键入 'const 标准::unique_ptr&'"

但我不确定我是否理解它的含义,因为我的理解是 it.second 返回对unique_ptr的引用,而不是它自己假设的 Foo 实例,这就是问题所在。需要做些什么来修复此示例?

编辑我使用的是较旧的g ++版本。

g++ (Ubuntu 4.8.4-2ubuntu1~14.04.3) 4.8.4

使用命令行。

g++ -std=c++11 -o unique unique.cpp

您遇到的错误是因为不允许将Foo*隐式转换为std::unique_ptr<Foo>。这是因为,获取原始指针的unique_ptr构造函数标记为 explicit

explicit
      unique_ptr(pointer __p) noexcept
      : _M_t(__p, deleter_type())
      { static_assert(!is_pointer<deleter_type>::value,
                     "constructed with null function pointer deleter"); }

因此,您应该创建一个unique_ptr并在执行emplace时对其进行move

注意:我不确定它为什么或如何在 g++> 6.0 库中工作。但我个人认为将原始指针隐式转换为智能指针是不安全的。要了解原因,请参阅:https://stackoverflow.com/a/11367997/434233

当我运行此代码时,投诉似乎与std::pair类的创建有关。

unique.unique_map.emplace(1, std::unique_ptr<Foo>(f1));
unique.unique_map.emplace(2, std::unique_ptr<Foo>(f2));

对我来说,这是构建和有效的,并不是说我可以肯定地说它真的会做你想要的。只是它为我编译和运行。

我C++大部分时间都在使用 QT 库和类,但是,在我看来,它未能找到一种方法将一对带有FOO*unique_ptr<FOO>