(void *)1是什么意思?

时间:2019-07-10 02:23:24

标签: c++ casting type-conversion ros typecasting-operator

我正在阅读ROS的代码。

在文件ros_comm/roscpp/include/ros/subscriber.h中,我看到了这样的一段代码:

operator void*() const { return (impl_ && impl_->isValid()) ? (void*)1 : (void*)0; }

好吧,(void *)0在C语言中可以看作是NULL,但是(void *)1是什么意思?

如果类Foo包含此函数,则意味着我们可以这样编写代码:

Foo foo;
void *ptr = foo;

对吗?那么这是否意味着void *ptr = (void *)1是可能的?这是什么意思?

2 个答案:

答案 0 :(得分:58)

这是避免在C ++ 11中引入bool上下文转换之前隐式转换为explicit的问题的老技巧。它旨在用于检查有效性:

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*可以避免该问题。


这些天这些技巧已经过时了。 C ++ 11引入了explicit转换。在explicit和循环的情况下考虑将bool转换为if,但在其他有问题的情况下则不考虑。这意味着这些天的转换应写为:

explicit operator bool() const { return impl_ && impl_->isValid(); }

答案 1 :(得分:0)

表明编写代码的人对他们使用的语言或工具不是很熟悉,或者代码已经存在了很长时间,并且被不同的人破解了。在过去的某个时候经历了从C到C ++的过渡,但仍带有一些旧的API合同(期望void*),可能难以更改。

如果您查看源代码,则没有理由这样做。 impl_是实现boost::shared_ptr<Impl>的{​​{1}},并且operator bool也返回Impl::isValid。除了bool之外,没有理由使用或返回任何内容。

基本上,这是一种扭曲的(并且可能是危险的)书写方式:

bool