В С++ 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
по умолчанию аргумент шаблона) - в отношении полноты: он представляет указатель, поэтому предоставляет все те же сопоставления, что и указатель, по сравнению с типом класса и должен быть менее сопоставимым для использования в ассоциативном контейнере, поэтому только это требование
Но я не понимаю, почему выбор изменяется в зависимости от типа интеллектуального указателя. Что мне не хватает?
Бонус/связанный: std::shared_ptr
, по-видимому, следовал из boost::shared_ptr
, а последний опускает другие реляционные операторы "по дизайну" (и поэтому std::shared_ptr
тоже). Почему это?