繁体   English   中英

C ++ static_cast从float **到void **

[英]C++ static_cast from float** to void**

刚碰到这个:

#include <iostream>

using namespace std;

int main(int argc, char** argv)
{
    float *a = new float[10];
    void **b;
    b = static_cast<void**>(&a);
    delete(a); 
    return 0;
}

macbook:C nils$ g++ -Wall -g -o static_cast static_cast.cpp 
static_cast.cpp: In function ‘int main(int, char**)’:
static_cast.cpp:9: error: invalid static_cast from type ‘float**’ to type ‘void**’
macbook:C nils$ clang++ -Wall -g -o static_cast static_cast.cpp 
static_cast.cpp:9:9: error: static_cast from 'float **' to 'void **' is not
      allowed
    b = static_cast<void**>(&a);
        ^~~~~~~~~~~~~~~~~~~~~~~
1 error generated.
macbook:C nils$ 

为什么不允许? 而b =(void **)(&a); 作品。

$ 5.2.9 / 2 -

“对于某些发明的临时变量t(8.5),如果声明”T t(e);“格式正确,则可以使用static_cast(e)形式的static_cast将表达式e显式转换为类型T.这种显式转换与执行声明和初始化相同,然后使用临时变量作为转换结果。如果T是引用类型(8.3.2),则结果为左值,否则为rvalue。当且仅当初始化将它用作左值时,表达式e才用作左值。“

让我们以下面的代码片段1为例

float *f;

void *p = f;

这里'p'的初始化是格式良好的。 这符合4.2美元

An rvalue of type “pointer to cv T,” where T is an object type, can be converted to an rvalue of type “pointer to cv void.”

现在让我们在OP中获取代码

在我们的例子中,“E”是'float **'而“T”是'void **'

因此,如果可以初始化'p',static_cast是否适用于尝试转换,如下所示

float **f;

void **p = f;

'p'的初始化是错误的,因为它不是$4.10下列出的有效条件

现在,为什么b = (void**)(&a); 作品?

这是使用显式强制转换的情况( $5.4 )。 在这种情况下,此显式强制转换等同于reinterpret_cast$5.4/5 )。 在这种特殊情况下,允许这种转换( $5.2.1/7 )。

这有帮助吗?

请参阅将void *转换为任何内容时是否应使用static_cast或reinterpret_cast

你应该使用reinterpret_cast

我已经使用静态强制转换从子类转换为父类,或者我知道类型转换是安全的。 如果我需要runt time验证,那么我会使用dynamic_cast。

当你编写C风格来演员时,你基本上是在规避C ++类型的检查,这是非常“宽容”的。 但是,为了符合C ++(并且为了安全起见),您应该使用C ++强制转换static_cast,dynamic_cast或reinterpret_cast。

reinterpret_cast是你在C ++中可以获得的最接近C-cast而不实际进行C-cast的。

由于Joe Gauterin在本评论中提到的原因,你可能不想要一个void** ,而是void*

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM