【问题标题】:C++0x Smart Pointer Comparisons: Inconsistent, what's the rationale?C++0x 智能指针比较:不一致,原因是什么?
【发布时间】:2011-04-25 04:19:39
【问题描述】:

在 C++0x (n3126) 中,可以比较智能指针,无论是关系还是相等。但是,这样做的方式对我来说似乎不一致。

例如shared_ptr定义operator<等价于:

template <typename T, typename U>
bool operator<(const shared_ptr<T>& a, const shared_ptr<T>& b)
{
    return std::less<void*>()(a.get(), b.get());
}

使用std::less 提供关于指针值的总排序,这与未指定的普通关系指针比较不同。

但是,unique_ptr 定义了相同的运算符:

template <typename T1, typename D1, typename T2, typename D2>
bool operator<(const unique_ptr<T1, D1>& a, const unique_ptr<T2, D2>& b)
{
    return a.get() < b.get();
}

它还以类似的方式定义了其他关系运算符。


为什么要改变方法和“完整性”?也就是说,为什么shared_ptr 使用std::lessunique_ptr 使用内置的operator&lt;?为什么shared_ptr 不提供其他关系运算符,例如unique_ptr

我能理解这两种选择背后的理由:

  • 关于方法:它表示一个指针,因此只需使用内置的指针运算符,而不是它需要在关联容器中可用,以便提供总排序(就像使用默认的 std::less 谓词获得的普通指针一样模板参数)
  • 关于完整性:它表示一个指针,因此提供与指针相同的所有比较,而它是一个类类型,只需要小于可比较即可在关联容器中使用,因此只提供该要求

但我不明白为什么选择 会根据智能指针类型而改变。我错过了什么?


奖励/相关:std::shared_ptr 似乎是从 boost::shared_ptr 继承而来的,后者“按设计”省略了其他关系运算符(std::shared_ptr 也是如此)。这是为什么呢?

【问题讨论】:

    标签: c++ c++11 std smart-pointers rationale


    【解决方案1】:

    这是 C++11 草案中的一个缺陷;打开了一个缺陷报告以将std::unique_ptr 关系运算符重载更改为使用std::less:请参阅LWG Defect 1297

    这是在最终的 C++11 规范中及时修复的。 C++11 §20.7.1.4[unique.ptr.special]/5 指定 operator&lt; 重载:

    返回: less&lt;CT&gt;()(x.get(), y.get())

    其中xy 是运算符的两个操作数,CT 是两个指针的共同类型(因为可以比较指向不同类型的指针,例如具有不同的cv 限定)。

    【讨论】:

    • 啊,我应该先看看那里。 :) 这肯定回答了方法的变化,但你知道为什么shared_ptr 不提供所有其他关系运算符吗?
    • @GMan:我认为这可能是一个错误。它们在 &lt;memory&gt; 概要中的 20.9 中列出,但它们实际上并不存在于 20.9.11.2.7...
    • @James:哦,好电话。我只是在shared_ptr 部分的范围内。好吧,我猜这解决了。 (他们真的应该把它清理干净。)谢谢。
    • 更奇怪的是:尽管其他三个关系运算符没有为shared_ptr 重载,但greatergreater_equalless_equal 类模板都专用于shared_ptr
    • @GMan:Boost 的基本原理似乎是这样的:因为您不能使用四个关系运算符比较 C++ 中的任意指针,除非这些指针指向某个数组或类的子对象并且因为你永远不会让 shared_ptrs 指向子对象(至少不是在 shared_ptr 的预期用途中),所以它们没有实现 shared_ptr 的关系运算符。但是,他们希望您能够使用 shared_ptr 作为映射键,并且由于某种原因,他们发现重载 op
    猜你喜欢
    • 2017-10-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-13
    • 1970-01-01
    • 2020-03-16
    相关资源
    最近更新 更多