Сравнение интеллектуальных указателей 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-квалификациями).