Сравнение интеллектуальных указателей C++0x: непоследовательное, в чем смысл?

В 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::less в то время как unique_ptr использует встроенный operator<? И почему нет shared_ptr также предоставьте другие реляционные операторы, такие как unique_ptr?

Я могу понять обоснование любого выбора:

  • по отношению к методу: он представляет указатель, поэтому просто используйте встроенные операторы указателя, вместо того, чтобы его можно было использовать в ассоциативном контейнере, чтобы обеспечить полное упорядочение (как в случае с указателем по умолчанию std::less аргумент шаблона предиката)
  • в отношении полноты: он представляет указатель, поэтому обеспечивает все те же сравнения, что и указатель, по сравнению с типом класса и должен быть менее сопоставим, чтобы использоваться в ассоциативном контейнере, поэтому необходимо обеспечить только это требование

Но я не понимаю, почему выбор меняется в зависимости от типа умного указателя. Что мне не хватает?


Bonus / связанные: std::shared_ptr кажется, следовало из boost::shared_ptr, а последний опускает другие реляционные операторы "по замыслу" (и так std::shared_ptr тоже) Почему это?

1 ответ

Решение

Это был дефект в черновиках 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())

где x а также y два операнда оператора и CT является общим типом двух указателей (поскольку можно сравнивать указатели на разные типы, например, с разными cv-квалификациями).

Другие вопросы по тегам