查找 unique_ptr 集合的原始指针

2024-04-24

我经常发现自己想要编写这样的代码:

class MyClass
{
public:
  void addObject(std::unique_ptr<Object>&& newObject);

  void removeObject(const Object* target);

private:
  std::set<std::unique_ptr<Object>> objects;
};

然而,大部分 std::set 接口对于 std::unique_ptrs 来说毫无用处,因为查找函数需要 std::unique_ptr 参数(我显然没有这些参数,因为它们由集合本身拥有)。

我可以想到两个主要的解决方案。

  1. 创建一个临时的 unique_ptr 用于查找。例如,上面的removeObject()可以这样实现:

    void MyClass::removeObject(const Object* target)
    {
      std::unique_ptr<Object> targetSmartPtr(target);
      objects.erase(targetSmartPtr);
      targetSmartPtr.release();
    }
    
  2. 用指向 unique_ptr 的原始指针映射替换该集合。

      // ...
      std::map<const Object*, std::unique_ptr<Object>> objects;
    };
    

然而,两者对我来说似乎都有点愚蠢。在解决方案 1 中,erase() 不是 noexcept,因此临时的 unique_ptr 可能会删除它并不真正拥有的对象,而解决方案 2 则不必要地需要双倍的容器存储空间。

我了解 Boost 的指针容器,但与现代 C++11 标准库容器相比,它们当前的功能有限。

我最近正在阅读有关 C++14 的内容,并发现“向关联容器添加异构比较查找”。但根据我的理解,查找类型必须与关键类型相当,但原始指针不能与 unique_ptrs 比较。

有人知道更优雅的解决方案或即将推出的 C++ 解决方案来解决这个问题吗?


In C++14 http://en.cppreference.com/w/cpp/container/set/find, std::set<Key>::find is a template函数如果Compare::is_transparent存在。您传入的类型不需要是Key,相当于您的比较器下的值。

所以写一个比较器:

template<class T>
struct pointer_comp {
  typedef std::true_type is_transparent;
  // helper does some magic in order to reduce the number of
  // pairs of types we need to know how to compare: it turns
  // everything into a pointer, and then uses `std::less<T*>`
  // to do the comparison:
  struct helper {
    T* ptr;
    helper():ptr(nullptr) {}
    helper(helper const&) = default;
    helper(T* p):ptr(p) {}
    template<class U, class...Ts>
    helper( std::shared_ptr<U,Ts...> const& sp ):ptr(sp.get()) {}
    template<class U, class...Ts>
    helper( std::unique_ptr<U, Ts...> const& up ):ptr(up.get()) {}
    // && optional: enforces rvalue use only
    bool operator<( helper o ) const {
      return std::less<T*>()( ptr, o.ptr );
    }
  };
  // without helper, we would need 2^n different overloads, where
  // n is the number of types we want to support (so, 8 with
  // raw pointers, unique pointers, and shared pointers).  That
  // seems silly:
  // && helps enforce rvalue use only
  bool operator()( helper const&& lhs, helper const&& rhs ) const {
    return lhs < rhs;
  }
};

然后使用它:

typedef std::set< std::unique_ptr<Foo>, pointer_comp<Foo> > owning_foo_set;

now, owning_foo_set::find会接受unique_ptr<Foo> or Foo* or shared_ptr<Foo>(或任何派生类Foo)并找到正确的元素。

在 C++14 之外,您被迫使用map to unique_ptr方法,或等效的东西,作为签名find限制过于严格。或者自己写set相等的。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

查找 unique_ptr 集合的原始指针 的相关文章

  • 以文化中立的方式将字符串拆分为单词

    我提出了下面的方法 旨在将可变长度的文本拆分为单词数组 以进行进一步的全文索引处理 删除停止词 然后进行词干分析 结果似乎不错 但我想听听关于这种实现对于不同语言的文本的可靠性的意见 您会建议使用正则表达式来代替吗 请注意 我选择不使用 S
  • Web 客户端和 Expect100Continue

    使用 WebClient C NET 时设置 Expect100Continue 的最佳方法是什么 我有下面的代码 我仍然在标题中看到 100 continue 愚蠢的 apache 仍然抱怨 505 错误 string url http
  • 为什么当实例化新的游戏对象时,它没有向它们添加标签? [复制]

    这个问题在这里已经有答案了 using System Collections using System Collections Generic using UnityEngine public class Test MonoBehaviou
  • HTTPWebResponse 响应字符串被截断

    应用程序正在与 REST 服务通信 Fiddler 显示作为 Apps 响应传入的完整良好 XML 响应 该应用程序位于法属波利尼西亚 在新西兰也有一个相同的副本 因此主要嫌疑人似乎在编码 但我们已经检查过 但空手而归 查看流读取器的输出字
  • OleDbDataAdapter 未填充所有行

    嘿 我正在使用 DataAdapter 读取 Excel 文件并用该数据填充数据表 这是我的查询和连接字符串 private string Query SELECT FROM Sheet1 private string ConnectStr
  • Clang 3.1 + libc++ 编译错误

    我已经构建并安装了 在前缀下 alt LLVM Clang trunk 2012 年 4 月 23 日 在 Ubuntu 12 04 上成功使用 GCC 4 6 然后使用此 Clang 构建的 libc 当我想使用它时我必须同时提供 lc
  • 不同枚举类型的范围和可转换性

    在什么条件下可以从一种枚举类型转换为另一种枚举类型 让我们考虑以下代码 include
  • 将多个表映射到实体框架中的单个实体类

    我正在开发一个旧数据库 该数据库有 2 个具有 1 1 关系的表 目前 我为每个定义的表定义了一种类型 1Test 1Result 我想将这些特定的表合并到一个类中 当前的类型如下所示 public class Result public
  • 显示UnityWebRequest的进度

    我正在尝试使用下载 assetbundle统一网络请求 https docs unity3d com ScriptReference Networking UnityWebRequest GetAssetBundle html并显示进度 根
  • while 循环中的 scanf

    在这段代码中 scanf只工作一次 我究竟做错了什么 include
  • 如何在 C 中调用采用匿名结构的函数?

    如何在 C 中调用采用匿名结构的函数 比如这个函数 void func struct int x p printf i n p x 当提供原型的函数声明在范围内时 调用该函数的参数必须具有与原型中声明的类型兼容的类型 其中 兼容 具有标准定
  • 如何序列化/反序列化自定义数据集

    我有一个 winforms 应用程序 它使用强类型的自定义数据集来保存数据进行处理 它由数据库中的数据填充 我有一个用户控件 它接受任何自定义数据集并在数据网格中显示内容 这用于测试和调试 为了使控件可重用 我将自定义数据集视为普通的 Sy
  • 垃圾收集器是否在单独的进程中运行?

    垃圾收集器是否在单独的进程中启动 例如 如果我们尝试测量某段代码所花费的进程时间 并且在此期间垃圾收集器开始收集 它会在新进程上启动还是在同一进程中启动 它的工作原理如下吗 Code Process 1 gt Garbage Collect
  • 如何查看网络连接状态是否发生变化?

    我正在编写一个应用程序 用于检查计算机是否连接到某个特定网络 并为我们的用户带来一些魔力 该应用程序将在后台运行并执行检查是否用户请求 托盘中的菜单 我还希望应用程序能够自动检查用户是否从有线更改为无线 或者断开连接并连接到新网络 并执行魔
  • 这些作业之间是否存在顺序点?

    以下代码中的两个赋值之间是否存在序列点 f f x 1 1 x 2 不 没有 在这种情况下 标准确实是含糊不清的 如果你想确认这一点 gcc 有这个非常酷的选项 Wsequence point在这种情况下 它会警告您该操作可能未定义
  • 如何使用 C# / .Net 将文件列表从 AWS S3 下载到我的设备?

    我希望下载存储在 S3 中的多个图像 但目前如果我只能下载一个就足够了 我有对象路径的信息 当我运行以下代码时 出现此错误 遇到错误 消息 读取对象时 访问被拒绝 我首先做一个亚马逊S3客户端基于我的密钥和访问配置的对象连接到服务器 然后创
  • WPF/C# 将自定义对象列表数据绑定到列表框?

    我在将自定义对象列表的数据绑定到ListBox in WPF 这是自定义对象 public class FileItem public string Name get set public string Path get set 这是列表
  • 向现有 TCP 和 UDP 代码添加 SSL 支持?

    这是我的问题 现在我有一个 Linux 服务器应用程序 使用 C gcc 编写 它与 Windows C 客户端应用程序 Visual Studio 9 Qt 4 5 进行通信 是什么very在不完全破坏现有协议的情况下向双方添加 SSL
  • C# 模拟VolumeMute按下

    我得到以下代码来模拟音量静音按键 DllImport coredll dll SetLastError true static extern void keybd event byte bVk byte bScan int dwFlags
  • C++ 标准是否指定了编译器的 STL 实现细节?

    在写答案时this https stackoverflow com questions 30909296 can you put a pimpl class inside a vector我遇到了一个有趣的情况 这个问题演示了这样一种情况

随机推荐

  • PHP CodeIgniter 框架中的命名空间

    CodeIgniter 支持命名空间吗 如何让命名空间在 Codeigniter 中工作 实际上 您可以让命名空间与应用程序模型中的相对路径结合使用 此修改使加载模型变得更加容易 并且还允许您拥有接口 将其添加到 application c
  • Akka HTTP 连接池在几个小时后挂起

    我有一个 HTTP 连接池 在运行几个小时后挂起 private def createHttpPool host String SourceQueue HttpRequest Promise HttpResponse val pool Ht
  • 图像中土壤颗粒分水岭以外的替代分割技术

    我正在寻找一种替代方法来分割以下土壤颗粒图像中的颗粒 而不是Python中的分水岭分割 因为它可能会误导对颗粒的正确检测 此外 我正在研究边缘检测图像 使用HED算法 作为附加 我希望找到一种更好的方法来分割颗粒以进行进一步处理 因为我想获
  • 如何根据 Pandas 中的间隔分配值

    我试图根据另一个数据帧的两个值之间的值向数据帧列分配一个值 intervals pd DataFrame columns From To Value data 0 100 A 100 200 B 200 500 C print interv
  • 如何知道之前的位置和新的位置?

    我有一个水平布局的回收视图 一次只有一个视图可见 mRecyclerView findViewById R id rvmain mRecyclerView setOnFlingListener null final SnapHelper s
  • 如何在Python 3.7中使用Pygame显示用Pillow加载的图像?

    我使用以下命令将图像导入到我的项目中 from PIL import Image myImage Image open myImageDirectory png 所以 myImage 现在作为 png 文件导入 但我想使用 Pygame 将
  • 通过 PHP cURL 获取文件内容 [关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 我有一个网站 我们就这样称呼它吧ht
  • flash、connect-flash 和express-flash 之间的区别

    我仍然对 flash connect flash 和 express flash 之间的区别感到有点困惑 安装 flashnpm install flash 快速闪存 npm install express flash 连接闪存 npm i
  • Symfony YAML 格式转换

    我有一些服务定义 如下所示 MyService class Some Class Here factory SomeFactoryHere method calls add service AnotherService1 create se
  • 从 CSV 文件读取数据并将其显示在 JTable 中

    我正在尝试从 CSV 文件读取数据并将其显示在 JTable 上 但遇到一些问题 我是菜鸟所以请耐心等待 我查看并合并了多个来源的示例代码 但无济于事 该表显示但它是空白的 我知道我正在读取数据 因为我可以打印它 我怀疑我的 ModelTa
  • 使用 require 与 fs.readFile 读取 json 文件内容

    假设对于来自 API 的每个响应 我需要将响应中的值映射到 Web 应用程序中的现有 json 文件 并显示 json 中的值 在这种情况下 读取 json 文件的更好方法是什么 require 或 fs readfile 请注意 可能有数
  • 当两个脚本实例同时写入日志时,为什么 Monolog 写入的日志行不会混乱/混合?

    当使用 Monolog 时StreamHandler 这是正常情况 PHP 脚本的多个实例会并行写入同一个日志文件 例如 在我的 Symfony 应用程序中 当多个用户同时打开 登录页面 时 会导致我的应用程序脚本出现多个实例 app ph
  • 在 GCP API 网关上使用 Google 访问令牌进行身份验证

    我正在尝试使用 Google 在 GCP API Gateway 上执行身份验证访问令牌 ya29 OAuth2 但是 那文档 https cloud google com api gateway docs authenticating u
  • 如何安装 Haskell 控制镜头

    我注意到 Control Lens 不是 Haskell 平台的一部分 所以我可能需要安装它 谁能解释一下如何安装吗 它不是 Haskell 平台的一部分吗 编辑 我正在使用 GHCi 它使用 prelude 警告 此答案仅适用于版本 3
  • 隐藏 primefaces 表列标题

    我有一个 p treeTable 树内容都在一列中 该树是一个共享组件 因此我的某些页面需要列标题 而有些则不需要 在列标题为空的页面中 它为列标题创建一个空行 这是我不想要的 我确实想要列内容 只是没有列标题时不需要标题 我怎样才能解决这
  • 从 Pyspark LDA 模型中提取文档主题矩阵

    我已经通过 Python API 在 Spark 中成功训练了 LDA 模型 from pyspark mllib clustering import LDA model LDA train corpus k 10 这工作得很好 但我现在需
  • 直接转到 URL 时,AngularJS 路径中带有参数的路由不会在 HTML5 模式下加载

    我指定了几条路线 app config routeProvider locationProvider function routeProvider locationProvider routeProvider when templateUr
  • 杀死 OpenCL 内核

    有没有办法通过 OpenCL API 终止正在运行的 OpenCL 内核 我在规范中没有找到任何内容 我能想到的唯一解决方案是 1 定期检查内核中主机希望内核停止时写入的标志 或 2 在单独的进程中运行内核并终止整个进程 我认为这两个都不是
  • ASP.NET 通过部分 ID 查找控件

    我的 html 中有这个 div div class myValue div 我动态添加我的单选按钮到那个div像这样 HtmlGenericControl div null foreach DataRow row in results R
  • 查找 unique_ptr 集合的原始指针

    我经常发现自己想要编写这样的代码 class MyClass public void addObject std unique ptr newObject void removeObject const Object target priv