2010-10-14 10 views
11

En C++ 0x (n3126), se pueden comparar punteros inteligentes, tanto relacionalmente como para la igualdad. Sin embargo, la forma en que esto se hace me parece inconsistente.C++ 0x Comparaciones inteligentes de punteros: Inconsistente, ¿cuál es el fundamento?

Por ejemplo, shared_ptr define operator< ser equivalente a:

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()); 
} 

Usando std::less proporciona orden total con respecto a valores de puntero, a diferencia de un vainilla comparación puntero relacional, que es no especificado.

Sin embargo, unique_ptr define el mismo operador como:

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(); 
} 

También definió los demás operadores relacionales de manera similar.


¿Por qué el cambio en el método y la "integridad"? Es decir, ¿por qué shared_ptr usa std::less mientras que unique_ptr usa el operator< incorporado? ¿Y por qué shared_ptr tampoco proporciona los otros operadores relacionales, como unique_ptr?

Puedo entender la razón de ser de una u otra opción:

  • con respecto al método: Representa un puntero de modo que sólo tiene que utilizar los operadores puntero incorporados, frente a lo que debe ser utilizable dentro de un contenedor asociativo así proporcionar orden total (como un puntero de vainilla con el argumento de plantilla de predicado predeterminado std::less)
  • con respecto a la integridad: representa un puntero, por lo que proporciona las mismas comparaciones que un puntero, frente a un tipo de clase y solo necesita ser menos que comparable para ser utilizado en un contenedor asociativo, por lo que solo se proporciona ese requisito

Pero no veo por qué la elección cambia dependiendo del tipo de puntero inteligente. ¿Qué me estoy perdiendo?


Bono/relacionados: std::shared_ptr parece haber seguido desde boost::shared_ptr, y éste omite los otros operadores relacionales "por diseño" (y así también lo hace std::shared_ptr). ¿Por qué es esto?

Respuesta

12

Esto era un defecto en los borradores de C++ 11; se abrió un informe de defectos para cambiar las sobrecargas del operador relacional std::unique_ptr para usar std::less: ver LWG Defect 1297.

Esto se corrigió a tiempo para la especificación final de C++ 11. C++ 11 §20.7.1.4 [unique.ptr.special]/5 especifica que el operator< de sobrecarga:

Devuelve:less<CT>()(x.get(), y.get())

donde x y y son los dos operandos de la operador y CT es el tipo común de los dos punteros (desde punteros a diferentes tipos, por ejemplo, con diferentes calificaciones de cv, se pueden comparar).

+0

Ah, debería haberlo visto primero. :) Definitivamente responde el cambio en el método, pero ¿sabes por qué 'shared_ptr' no proporcionaría todos los demás operadores relacionales? – GManNickG

+0

@GMan: Creo que eso podría ser un error. Se enumeran en 20.9 en la sinopsis '', pero en realidad no están presentes en 20.9.11.2.7 ... –

+0

@James: Ah, buen nombre. Solo me referí a la sección 'shared_ptr'. Bueno, eso resuelve eso, supongo. (Realmente deberían limpiar eso.) Gracias. – GManNickG

Cuestiones relacionadas