2011-05-19 10 views
13

En C++ 0x, hay std :: static_pointer_cast para std :: shared_ptr, pero no hay un método equivalente para std :: weak_ptr. Es esto intencional, o un descuido? Si es un descuido, ¿cómo definiría una función apropiada?static_pointer_cast para weak_ptr

Respuesta

9

Esto debe hacerlo por usted:

template<class T, class U> 
std::weak_ptr<T> 
static_pointer_cast(std::weak_ptr<U> const& r) 
{ 
    return std::static_pointer_cast<T>(std::shared_ptr<U>(r)); 
} 

Esto lanzará una excepción si el weak_ptr ha expirado. Si prefiere obtener un nulo weak_ptr, entonces use r.lock().

+0

¿Conoces la historia de esto en absoluto? Dado lo trivial que fue escribir esto, me pregunto por qué el comité de normas no lo incluyó. – tgoodhart

+2

Acabo de escanear los documentos estándares, y me parece que nadie lo propuso. Tampoco puedo encontrar un registro de que se solicite o propuse en boost (la fuente original de std :: weak_ptr). Quizás la razón es que es trivial escribir, y no trivial para elegir la política adecuada (throw o null). Y proporcionar dos funciones (una para cada política) es subóptima porque 'static_pointer_cast' pretende ser un nombre genérico, utilizable en código donde el tipo de puntero es genérico. –

2

versión de Howard es correcta, pero en muchos casos, tiene sentido para pasar simplemente weakptr.lock() como parámetro para std :: static_pointer_cast:

std::weak_ptr<A> a = ...; 
std::weak_ptr<B> b = std::static_pointer_cast<B>(a.lock()); 

Esta sintaxis muestra explícitamente lo que está pasando, y marcas código fácil de leer

+0

Parece que hay un error aquí. Como a.lock() es temporal, el puntero subyacente podría eliminarse mientras el código subsiguiente a esto todavía esté usando b. - De hecho, después de leer static_pointer_cast docs nuevamente, estoy equivocado. Devuelve un puntero compartido que se comparte con el puntero compartido subyacente de un objeto. –

0

La omisión es intencional porque, a pesar de su nombre, std :: weak_ptr no es un tipo de puntero y no proporciona una interfaz de puntero (operator ->, operator *, static_pointer_cast, etc.).

Cuestiones relacionadas