c++ - std::owner_less 做什么?
问题描述
我读过 std::owner_less 执行“基于所有者而不是基于值”的排序,如果两个智能指针“指向同一对象的子对象”,它们是等效的——这到底是什么意思?
作为测试用例,我编写了以下代码:
struct T {};
int main() {
T* t = new T();
std::shared_ptr<T> a(t);
std::shared_ptr<T> b(t);
std::set<std::shared_ptr<T>> set1;
set1.insert(a);
std::cout << set1.size() << std::endl;
set1.insert(b);
std::cout << set1.size() << std::endl;
std::set<std::shared_ptr<T>, std::owner_less<std::shared_ptr<T>>> set2;
set2.insert(a);
std::cout << set2.size() << std::endl;
set2.insert(b);
std::cout << set2.size() << std::endl;
}
并且输出是 1 1 1 2。在我看来,如果 std::owner_less 执行“基于所有者”的比较,它不应该认为 a 和 b 相同,而默认比较器将它们视为不同吗?我的代码的结果似乎正好相反。
解决方案
std::shared_ptr<T> a(t);
std::shared_ptr<T> b(t);
shared_ptr
当s 被销毁时,这是未定义的行为;两个shared_ptr
不知道对方的存在,都会尝试删除t
。
owner_less
可以被认为是“对(真实或隐喻)控制块的地址进行排序”。因此,如果它们共享所有权或都为空,则它认为等效的两个shared_ptr
(and ):weak_ptr
struct T { int x, y; };
std::shared_ptr<T> a(new T{});
std::shared_ptr<T> b = a;
std::shared_ptr<int> c(a, &a->y); // aliasing constructor
std::shared_ptr<T> d(a.get(), [](T*){}); // null deleter to avoid no double delete
std::shared_ptr<T> e(std::shared_ptr<T>(), a.get()); // "non-owning" empty shared_ptr with a non-null stored pointer
a
, b
, 和c
都是等价的,owner_less
因为它们共享所有权。d
不与a
(它有自己的“控制块”)共享所有权,因此根据owner_less
. 同样 for e
,它是空的(不拥有任何东西)但有一个非空的存储指针。
默认比较器只是比较存储的指针或get()
. 它将看到a
、b
、d
和e
,它们都是等效c
的和不同的(假设您将两边都转换为,shared_ptr<void>
以便它们具有可比性)。
推荐阅读
- python - 无法在 Flask 的生产服务器中启用调试模式
- powershell - Powershell在通过文件夹递归时将文件保存在原始文件夹中
- c# - 加密自定义 .config 文件 .NET
- pyspark - Databricks - 显示数据框并打印字符串
- vim - 如何让折叠 expr 在 vim 8 中与终端一起使用
- ruby - 无法从 ruby 文件中解析行
- node.js - 在 IBM Cloud 函数中通过 NODE.JS 发送邮件
- c# - 如何在DataTable c#中创建用于计算不同值的新列
- asp.net-mvc - MVC 中的 POST 表单 - 没有值被写入数据库
- cygwin - Linaro gcc 在 Windows 上失败