C ++ оператор равенства shared_ptr - PullRequest
10 голосов
/ 20 апреля 2011

Оператор равенства для shared_ptr определен следующим образом:

template<class T, class U> inline bool operator==(
    shared_ptr<T> const & a, shared_ptr<U> const & b)
{
    return a.get() == b.get();
}

Это выглядит неработоспособным.Разве не лучше было бы направить равенство на то, на что указывают a и b?Или это будет несправедливым ограничением для пользователей библиотеки (в том смысле, что они должны предоставлять оператор равенства)?

Если у меня есть карта или хеш-таблица, содержащая shared_ptrs, то текущее определение делает равенство непригодным для использования.Например, рассмотрим

std::map<int, std::tr1::shared_ptr<T> > m1, m2;

Не хотим ли мы проверить, что ptrs для каждого целого в m1 и m2 указывают на одно и то же значение?

Я могу реализовать свое собственное равенство, выровняв m1, m2 out (создавая множества из каждого, разыменовывая shared_ptrs по пути).Есть ли уловка STL, которая позволит выполнить этот или какой-либо другой способ аккуратно проверить равенство при наличии shared_ptrs?

Ответы [ 3 ]

40 голосов
/ 20 апреля 2011

Он не нарушен, поскольку shared_ptr концептуально является указателем, поэтому он реализует по указателю равенство. Когда вы проверяете два указателя на равенство, вы хотите знать, указывают ли они на одно и то же место в памяти.

6 голосов
/ 20 апреля 2011

Я думаю, что идея состоит в том, что сравнение двух экземпляров shared_ptr примерно так же полезно, как сравнение двух указателей.Если вы хотите std::map, содержащий shared_ptr s или простые старые указатели на объекты, вам придется переопределить предикат чем-то, что сравнивает указываемые объекты в любом случае.1007 * В случае сравнения двух карт вы, вероятно, захотите использовать версию std::equal, которая принимает предикат.

0 голосов
/ 05 июля 2015

Просто столкнулся с проблемой, где я мог использовать оба типа эквивалентности.Неупорядоченный набор shared_ptr, где я хотел, чтобы эквивалентность основывалась на содержимом указанных объектов.Это может быть реализовано с использованием шаблонной специализации hash и перегруженного ==.Теперь у меня есть другой контейнер, который также содержит эти указатели (своего рода список инцидентности ребер), но, поскольку мы уже знаем, что они уникальны, потому что мы использовали набор, мы можем положиться на эквивалентность указателей.Хотя исходная эквивалентность также будет работать, возможно, было бы более эффективно просто полагаться на эквивалентность указателя во втором случае - это зависит от количества данных, которые находятся в сравниваемых экземплярах.

Итак, чтобыОтвет на вопрос.Нет, это не было бы лучше, потому что то, как вы используете предоставленную гибкость, зависит от решаемой проблемы.

...