Что означает (void *) 1?
Я читаю код ROS.
В файле ros_comm/roscpp/include/ros/subscriber.h
я вижу такой фрагмент кода:
operator void*() const { return (impl_ && impl_->isValid()) ? (void*)1 : (void*)0; }
Ну, (void *)0
можно рассматривать как NULL
в C, но что означает (void *)1
?
Если класс Foo
содержит эту функцию, это означает, что мы можем кодировать так:
Foo foo;
void *ptr = foo;
Правильно? Значит ли это, что void *ptr = (void *)1
возможен? Что это значит?
Ответы
Ответ 1
Это старый прием, позволяющий избежать проблем с неявными преобразованиями в bool
до появления explicit
контекстных преобразований в С++ 11. Он предназначен для проверки действительности:
Subscriber my_subscriber = someFunction();
if (!my_subscriber) {
// error case
}
Важным моментом является то, что не существует встроенного преобразования из типа void*
в целочисленные типы, но существует тип от bool
до целочисленных типов. В то же время существует встроенное преобразование из void*
в bool
. Это означает, что если вы определяете неявное преобразование в bool
, то на удивление верно следующее:
void my_func(int i);
void another_func() {
Subscriber sub = something();
my_func(sub);
}
Определение преобразования в void*
позволяет избежать этой проблемы.
В наши дни этот трюк устарел. С++ 11 ввел explicit
преобразования. explicit
преобразования в bool
рассматриваются в условиях циклов if
и, но не рассматриваются в других проблемных случаях. Это означает, что в наши дни это преобразование должно быть записано как:
explicit operator bool() const { return impl_ && impl_->isValid(); }
Ответ 2
Это показывает, что либо человек, который написал код, не очень хорошо знаком с языком или инструментами, которые они используют, либо код был в течение долгого и долгого времени и был взломан разными людьми, по-видимому, подвергся Переход от C к С++ в прошлом, все еще несущий некоторый устаревший контракт API (ожидающий void*
), который может быть проблематичным для изменения.
Нет веских причин делать такие вещи, если вы посмотрите на источник. impl_
является boost::shared_ptr<Impl>
который реализует operator bool
, и Impl::isValid
возвращает bool
. Там нет никаких оснований для использования или возврата чего-либо, кроме bool
любом месте.
По сути, это искаженный (и, возможно, опасный) способ написания:
return impl_ && impl_->isValid();