11

在 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());
}

Usingstd::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_ptruse std::lesswhileunique_ptr使用内置的operator<?为什么不shared_ptr提供其他关系运算符,例如unique_ptr

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

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

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


Bonus/related:std::shared_ptr似乎来自boost::shared_ptr,后者“设计”省略了其他关系运算符(也是如此std::shared_ptr)。为什么是这样?

4

1 回答 1

12

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

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

回报: less<CT>()(x.get(), y.get())

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

于 2010-10-14T02:17:00.567 回答