web-dev-qa-db-fra.com

Que signifie (vide *) 1?

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?

45
Yves

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(); }
68
Miles Budnek