刚碰到这个:
#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$
Run Code Online (Sandbox Code Playgroud)
为什么不允许?而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).
这有帮助吗?