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

时间:2010-09-02 08:36:08

标签: c++

刚碰到这个:

#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 **)(&amp; a);作品。

4 个答案:

答案 0 :(得分:7)

$ 5.2.9 / 2 -

  

“表达式e可以明确表达   使用a转换为类型T.   static_cast的形式   static_cast(e)如果声明   对于某些人来说,“T t(e);”格式正确   发明了临时变量t(8.5)。   这种明确的效果   转换与执行相同   声明和初始化和   然后使用临时变量作为   转换的结果。该   如果T是a,则结果是左值   引用类型(8.3.2)和右值   除此以外。表达式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)。

这有帮助吗?

答案 1 :(得分:2)

请参阅Should I use static_cast or reinterpret_cast when casting a void* to whatever

你应该使用reinterpret_cast

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

答案 2 :(得分:1)

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

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

答案 3 :(得分:1)

您可能不想要void**,而是void*,原因是Joe Gauterin在this comment

中提到的原因