c++ - ¿Qué significa(vacío*) 1
casting type-conversion (2)
Este es un viejo truco para evitar problemas con las conversiones implícitas a
bool
desde antes de que
explicit
conversiones contextuales
explicit
se introdujeran en C ++ 11.
Está destinado a ser utilizado para verificar la validez:
Subscriber my_subscriber = someFunction();
if (!my_subscriber) {
// error case
}
El punto importante es que no existe una conversión integrada desde
void*
a tipos enteros, pero sí existe una conversión de
bool
a tipos enteros.
Al mismo tiempo, existe una conversión incorporada de
void*
a
bool
.
Eso significa que si define una conversión implícita a
bool
, lo siguiente es sorprendentemente válido:
void my_func(int i);
void another_func() {
Subscriber sub = something();
my_func(sub);
}
Definir una conversión para
void*
evita ese problema.
Estos días ese truco es obsoleto sin embargo.
C ++ 11 introdujo conversiones
explicit
.
explicit
conversiones
explicit
a
bool
se consideran en las condiciones de
if
y loops, pero no se consideran en otros casos problemáticos.
Eso significa que en estos días esa conversión debe escribirse como:
explicit operator bool() const { return impl_ && impl_->isValid(); }
Estoy leyendo el código de ROS .
En el archivo
ros_comm/roscpp/include/ros/subscriber.h
, veo un código de este tipo:
operator void*() const { return (impl_ && impl_->isValid()) ? (void*)1 : (void*)0; }
Bueno,
(void *)0
puede considerarse
NULL
en C, pero ¿qué significa
(void *)1
?
Si una clase
Foo
contiene esta función, significa que podemos codificar así:
Foo foo;
void *ptr = foo;
¿Derecha?
Entonces, ¿significa que
void *ptr = (void *)1
es posible?
¿Qué significa esto?
Muestra que la persona que escribió el código no está muy familiarizada con el lenguaje o las herramientas que está utilizando, o que el código ha estado presente durante mucho, mucho tiempo y ha sido pirateado por diferentes personas, presumiblemente habiendo sufrido un error. Transición de C a C ++ en algún momento en el pasado, aún con algún contrato de API heredado (esperando un
void*
) que puede ser problemático cambiar.
No hay una
buena
razón para hacer tal cosa, si nos fijamos en la fuente.
impl_
es un
boost::shared_ptr<Impl>
que implementa el
operator bool
, y
Impl::isValid
devuelve
bool
.
No hay razón para usar, o devolver cualquier cosa excepto
bool
cualquier lugar.
Básicamente, esta es una forma contorsionada (y posiblemente peligrosa) de escribir:
return impl_ && impl_->isValid();