c++ - unique_ptr - ¿Cómo shared_ptr<> permite de forma segura el lanzamiento de bool?
unique_ptr c++ (3)
Estaba investigando cómo std::tr1::shared_ptr<>
proporciona la capacidad de convertir a bool. Me quedé atrapado en el pasado al intentar crear un puntero inteligente que se puede convertir en bool como la solución trivial, es decir,
operator bool() {
return m_Ptr!=0;
}
por lo general, termina siendo moldeable implícitamente para el tipo de puntero (presumiblemente por tipo de promoción), lo que generalmente es indeseable. Tanto el impulso como las implementaciones de Microsoft parecen usar un truco que implica la conversión a un unspecified_bool_type()
. ¿Alguien puede explicar cómo funciona este mecanismo y cómo evita la conversión implícita al tipo de puntero subyacente?
El truco funciona así. Usted define todo esto dentro de su tipo de puntero inteligente (en este caso, shared_ptr
):
private:
struct Tester
{
Tester(int) {} // No default constructor
void dummy() {}
};
typedef void (Tester::*unspecified_bool_type)();
public:
operator unspecified_bool_type() const
{
return !ptr_ ? 0 : &Tester::dummy;
}
ptr_
es el puntero nativo dentro de la clase de puntero inteligente.
Como puede ver, unspecified_bool_type
es un typedef
a un tipo al que ningún código externo puede acceder, ya que Tester
es una estructura privada. Pero el código de llamada puede usar esta conversión (implícita) a un tipo de puntero y verificar si es nulo o no. Que, en C ++, se puede utilizar como una expresión bool
.
La técnica descrita en la pregunta es el lenguaje bool seguro .
A partir de C ++ 11, ese idioma ya no es necesario. La solución moderna al problema es usar la palabra clave explicit
en el operador:
explicit operator bool() {
return m_Ptr != nullptr;
}
Por lo general, lo que devuelve es un puntero de miembro. Los punteros de los miembros pueden tratarse como un bool
pero no admiten muchas de las conversiones implícitas que hace bool
.