2011-04-19 13 views
8

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

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 la que a y b apuntan? ¿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 un hash_table que contenga shared_ptrs, entonces la definición actual hace que la igualdad no se pueda usar. Por ejemplo, consideremos

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

no es cierto que desee comprobar que los PAD para cada int en M1 y M2 están señalando en el mismo valor?

Puedo implementar mi propia igualdad aplanando m1, m2 (construyendo conjuntos de cada uno, desreferenciando shared_ptrs a lo largo del camino). ¿Hay algún truco de STL que logre este o alguna otra forma de probar la igualdad en presencia de shared_ptrs ordenadamente?

+7

Depende de lo que quiere decir con igualdad. Para punteros ordinarios, eso significa "señalar el mismo objeto". Para mí, parece razonable extender este concepto de igualdad a shared_pointer. –

Respuesta

5

Creo que la idea es que comparar dos instancias de shared_ptr es tan útil como comparar dos punteros. Si quiere un std::map que contenga shared_ptr s o simples punteros a objetos, tendrá que anular el predicado con algo que compare los objetos apuntados en ambos casos.

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

31

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

0

Acabo de encontrarme 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.

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

Cuestiones relacionadas