c++ casting type-conversion ros typecasting-operator

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