Je lis le code de ROS .
Dans le fichier ros_comm/roscpp/include/ros/subscriber.h
, Je vois un tel morceau de code:
operator void*() const { return (impl_ && impl_->isValid()) ? (void*)1 : (void*)0; }
Eh bien, (void *)0
Peut être considéré comme NULL
en C, mais que signifie (void *)1
?
Si une classe Foo
contient cette fonction, cela signifie que nous pouvons coder comme ceci:
Foo foo;
void *ptr = foo;
Droite? Cela signifie-t-il donc que void *ptr = (void *)1
est possible? Qu'est-ce que ça veut dire?
C'est une vieille astuce pour éviter les problèmes avec les conversions implicites en bool
d'avant explicit
les conversions contextuelles ont été introduites dans C++ 11. Il est destiné à être utilisé pour vérifier la validité:
Subscriber my_subscriber = someFunction();
if (!my_subscriber) {
// error case
}
Le point important est qu'aucune conversion intégrée n'existe à partir de void*
aux types entiers, mais un existe de bool
aux types entiers. Dans le même temps, une conversion intégrée de void*
à bool
existe. Cela signifie que si vous définissez une conversion implicite en bool
, ce qui suit est étonnamment valide:
void my_func(int i);
void another_func() {
Subscriber sub = something();
my_func(sub);
}
Définition d'une conversion en void*
évite ce problème.
De nos jours, cette astuce est obsolète. C++ 11 a introduit les conversions explicit
. explicit
les conversions en bool
sont prises en compte dans les conditions de if
et les boucles, mais ne sont pas prises en compte dans d'autres cas problématiques. Cela signifie que ces jours-ci, cette conversion doit s'écrire:
explicit operator bool() const { return impl_ && impl_->isValid(); }