Pregunta C ++ shared_ptr equality operator


El operador de igualdad para shared_ptr se define de la siguiente manera:

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

Esto parece roto. ¿No hubiera sido mejor enviar la igualdad a lo que a y b están apuntando a? O sería una restricción injusta para los usuarios de la biblioteca (en ese tienen que proporcionar un operador de igualdad)?

Si tengo un mapa o una tabla hash que contiene shared_ptrs, entonces la definición actual hace la igualdad inutilizable. Por ejemplo, considere

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

¿No deseamos comprobar que las ptrs para cada int en m1 y m2 apuntan al mismo valor?

Puedo implementar mi propia igualdad aplanando m1, m2 (construyendo conjuntos de cada uno, desreferenciando shared_ptrs en el camino). ¿Hay algún truco de STL que logre esto? o de alguna otra manera para probar la igualdad en presencia de shared_ptrs pulcramente?


9
2018-04-19 21:33


origen


Respuestas:


No está roto, porque un shared_ptr es conceptualmente un puntero, por lo tanto implementa puntero igualdad. Cuando prueba dos punteros para la igualdad, desea saber si apuntan al mismo lugar en la memoria.


37
2018-04-19 21:41



Creo que la idea es que comparar dos shared_ptr instancias es tan útil como comparar dos punteros. Si quieres un std::map conteniendo shared_ptrs o simples punteros antiguos a los objetos, tendrás que anular el predicado con algo que compare los objetos apuntados en cualquier caso.

En el caso de comparar dos mapas, es probable que desee utilizar la versión de std::equal eso toma un predicado.


6
2018-04-19 21:39



Acabo de toparme con un problema donde podría usar ambos tipos de equivalencia. Un conjunto desordenado de shared_ptr donde quería que la equivalencia se basara en los contenidos de los objetos apuntados. Esto se puede implementar usando una plantilla de especialización de hash y una sobrecarga ==. Ahora tengo otro contenedor que también contiene estos punteros (una especie de lista de incidencia de bordes), pero como ya sabemos que son únicos porque utilizamos el conjunto, podemos confiar en la equivalencia del puntero. Aunque la equivalencia original también funcionaría, podría ser más eficiente simplemente confiar en la equivalencia del puntero en el segundo caso, esto depende de la cantidad de datos que se encuentran en las instancias que se comparan.

Entonces, para responder la pregunta. No, no hubiera sido mejor, porque la forma de usar la flexibilidad proporcionada depende del problema que se esté resolviendo.


0
2017-07-05 19:42