C++ std::owner_less用法 _ 在容器中按所有权排序指针【干货】

云磊同学_8126

云磊同学_8126

2026-04-15

533人浏览

原创

std::owner_less 是 c++ 标准库中用于基于所有权比较智能指针(如 shared_ptr、weak_ptr)的函数对象,其核心调用 owner_before;不能直接用 operator 是因所有权比较非值比较,且 operator

c++ std::owner_less用法 _ 在容器中按所有权排序指针【干货】

std::owner_less 是什么,为什么不能直接用 operator 比较智能指针

它不是用来“排序原始指针”的工具,而是专为 std::shared_ptr 和 std::weak_ptr 设计的比较器,解决“相同对象、不同 shared_ptr 实例”之间的等价性问题。默认的 operator 比较的是控制块地址(即指针本身),而 <code>std::owner_less 比较的是所管理对象的地址 —— 也就是“谁拥有同一个对象”。

常见错误现象:
- 把多个 shared_ptr 指向同一对象插入 std::set<shared_ptr>, owner_less<shared_ptr>>></shared_ptr></shared_ptr>,结果只存一个(正确);但若用默认比较器,会存多个(逻辑错误)。

  • 使用场景:需要以“对象身份”而非“指针实例身份”去重或排序,比如缓存、资源索引表
  • 不适用于 unique_ptr 或裸指针 —— 它们没有共享所有权语义,owner_less 对它们无定义行为
  • 性能影响极小:只是多一次解引用取 get(),和普通函数调用开销相当

在 std::set 和 std::map 中正确传入 owner_less

必须显式指定模板参数,且类型要和容器元素严格匹配;否则编译失败或行为未定义。

std::set<:shared_ptr>, std::owner_less<:shared_ptr>>> ptr_set;
std::map<:shared_ptr>, std::string, std::owner_less<:shared_ptr>>> lookup;
</:shared_ptr></:shared_ptr></:shared_ptr></:shared_ptr>
  • owner_less<shared_ptr>></shared_ptr> 和 owner_less<weak_ptr>></weak_ptr> 是两个独立类型,不能混用
  • 如果容器里是 weak_ptr,必须写 owner_less<weak_ptr>></weak_ptr>,哪怕它指向的对象和某个 shared_ptr 相同
  • 不要试图把 owner_less<void></void> 当泛型万能写法 —— C++17 起已弃用,C++20 删除

和 std::less<shared_ptr>></shared_ptr> 的关键区别在哪

std::less<shared_ptr>></shared_ptr> 是对 shared_ptr 对象本身的字典序比较(基于控制块地址),而 std::owner_less 基于所指对象地址(get() 返回值)。这是根本差异。

C++ Code Review Master
C++ Code Review Master

组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。

下载

示例:

auto p1 = std::make_shared<int>(42);
auto p2 = p1; // 共享同一对象
// p1.get() == p2.get() → true
// owner_less(p1, p2) → false(相等)
// less<shared_ptr>>(p1, p2) → implementation-defined(可能 true,也可能 false)
</shared_ptr></int>
  • 当需要“同一对象只算一个键”时,owner_less 是唯一可靠选择
  • std::less<shared_ptr>></shared_ptr> 在某些标准库实现中会退化为 get() 比较,但这是非强制要求,不可依赖
  • 跨线程使用时,owner_less 不访问控制块内部状态,线程安全;而依赖控制块地址的比较器可能引发竞态(尽管罕见)

容易被忽略的陷阱:循环引用 + owner_less 导致内存泄漏

这不是 owner_less 的 bug,但组合使用时极易踩坑:用 owner_less 组织的容器若持有 shared_ptr,又反过来被该对象的成员变量持有(如 shared_from_this()),就可能形成无法析构的环。

  • 典型模式:class Node { std::shared_ptr<node> parent; };</node>,再把所有 Node 放进 owner_less set —— 若 parent 指向也在该 set 中,refcount 永远不为 0
  • 调试线索:对象析构函数不执行,Valgrind 显示 still-reachable 内存,use_count() 始终 ≥2
  • 解法不是放弃 owner_less,而是改用 weak_ptr 存储反向引用,或用外部索引(如 std::map<uintptr_t shared_ptr>></uintptr_t>)替代

真正难处理的从来不是怎么写这行模板,而是想清楚“这个容器到底该按什么维度去重”——对象身份?实例身份?生命周期归属?owner_less 只忠实地执行前者,其余都得你来设计。

C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

c++

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
c++和c语言的区别有哪些
c++和c语言的区别有哪些

c++和c语言的区别:1、面向对象编程(OOP)支持不同;2、新增特性不同;3、标准库不同;4、编译方式不同;5、命名空间不同等等。想了解更多c++的相关内容,可以阅读本专题下面的文章。

2024.03.14

2228

9

c++和python学习顺序推荐
c++和python学习顺序推荐

一般建议先学习C++,再学习Python,因为这样可以逐步从较为底层的编程语言向更高级的语言过渡。想了解更多python的相关内容,可以阅读本专题下面的文章。

2024.03.14

999

6

python和c++学习性价比分析
python和c++学习性价比分析

Python易于学习,广泛应用于Web开发、数据科学和人工智能等领域,但性能较低。C语言性能高,适用于对性能要求较高的场景,如游戏开发和系统编程,但学习曲线陡峭,错误处理复杂。想了解更多python的相关内容,可以阅读本专题下面的文章。

2024.03.14

427

5

c语言和c++一样吗
c语言和c++一样吗

c语言和c++是两种不同的编程语言,虽然有相似之处,但存在显著差异。c语言专注于过程式编程和系统级开发,以简洁、高效著称。c++作为c语言的超集,引入了面向对象编程,增强了代码组织和管理能力,但学习曲线也更陡峭。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.03.14

307

5

c语言和c++先学哪个好
c语言和c++先学哪个好

初学者选择学习c语言还是c++语言,需要根据个人学习目标、背景以及编程兴趣和预期应用方向来决定。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.03.14

406

5

c语言和c++的区别和联系
c语言和c++的区别和联系

c语言和c++是计算机科学领域应用广泛的编程语言。虽然它们有着相似的基础,但它们在语言类型、语法功能和内存管理方面存在着显著差异。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.03.14

580

5

c++软件中文更改教程
c++软件中文更改教程

对于 ide,可通过打开设置,找到语言设置,选择中文,并保存更改。对于非 ide 应用程序,可查找设置或选项,选择语言设置,更改为中文,并保存更改。想了解更多c++的相关内容,可以阅读本专题下面的文章。

2024.03.21

1389

9

python和java和c++学习性价比分析
python和java和c++学习性价比分析

Python以其易学性、丰富的库和活跃的社区而著称,适合数据科学、人工智能和Web开发。Java以其跨平台性、企业级应用开发和Android应用开发而闻名。C++以其底层控制能力、高效性能和游戏开发而著称。选择哪种语言取决于个人兴趣、职业方向和特定需求。想了解更多python和java和c++的相关内容,可以阅读本专题下面的文章。

2024.03.22

1197

7

c++和c语言学习顺序推荐
c++和c语言学习顺序推荐

对于初学者,建议先学习C语言,掌握编程基础后再转入C++,便于理解面向对象编程概念。有编程经验者可直接学习C++,快速接触高级编程技术。想了解更多c++和c语言的相关内容,可以阅读本专题下面的文章。

2024.03.25

1325

9

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Conan 2 Essentials 免费课程
Conan 2 Essentials 免费课程

共0课时 | 0人学习

CMake 与 Conan 集成实践
CMake 与 Conan 集成实践

共0课时 | 0人学习

Conan 2 高级依赖模型介绍
Conan 2 高级依赖模型介绍

共0课时 | 0人学习