C++ 为什么我可以将静态_cast与void*一起使用,而不能与char一起使用*

C++ 为什么我可以将静态_cast与void*一起使用,而不能与char一起使用*,c++,casting,reinterpret-cast,strict-aliasing,static-cast,C++,Casting,Reinterpret Cast,Strict Aliasing,Static Cast,我知道它主要用于进出char* 但我惊讶地发现,在void*中也可以这样做。例如: auto foo "hello world"s; auto temp = static_cast<void*>(&foo); auto bar = static_cast<string*>(temp); autofoo“helloworld”s; 自动温度=静态施法(&foo); 自动条=静态浇铸(温度); 在static\u cast和void*上使用reinterpret\

我知道它主要用于进出
char*

但我惊讶地发现,在
void*
中也可以这样做。例如:

auto foo "hello world"s;
auto temp = static_cast<void*>(&foo);
auto bar = static_cast<string*>(temp);
autofoo“helloworld”s;
自动温度=静态施法(&foo);
自动条=静态浇铸(温度);

static\u cast
void*
上使用
reinterpret\u cast
char*
有什么好处?这与严格的别名问题有关吗?

一般来说,
static\u cast
将执行任意两种类型的强制转换,如果其中一种类型可以隐式转换为另一种类型。这包括算术强制转换、向下强制转换、向上强制转换和从
void*
向上强制转换

也就是说,如果此强制转换有效:

void foo(A a);
B b;
foo(b);
然后
static_cast(a)
static_cast(b)
也将有效

由于任何指针都可以隐式转换为
void*
,因此您的特殊行为

重新解释\u cast
通过重新解释值的位模式进行转换。正如您在问题中所说,这通常是为了在不相关的指针类型之间进行转换

是的,您可以使用两个
静态\u cast
,通过
void*
在不相关的指针类型之间进行转换:

B *b;
A *a1 = static_cast<A*>(b); //compiler error
A *a2 = static_cast<A*>(static_cast<void*>(b)); //it works (evil laugh)!
B*B;
A*a1=静态铸件(b)//编译错误
A*a2=静态施法(静态施法(b))//它有效(邪恶的笑声)!

但这违反了规则。如果您确实需要,只需使用
重新解释\u cast

一般来说,
静态\u cast
将执行任意两种类型的强制转换,前提是其中一种可以隐式转换为另一种。这包括算术强制转换、向下强制转换、向上强制转换和从
void*
向上强制转换

也就是说,如果此强制转换有效:

void foo(A a);
B b;
foo(b);
然后
static_cast(a)
static_cast(b)
也将有效

由于任何指针都可以隐式转换为
void*
,因此您的特殊行为

重新解释\u cast
通过重新解释值的位模式进行转换。正如您在问题中所说,这通常是为了在不相关的指针类型之间进行转换

是的,您可以使用两个
静态\u cast
,通过
void*
在不相关的指针类型之间进行转换:

B *b;
A *a1 = static_cast<A*>(b); //compiler error
A *a2 = static_cast<A*>(static_cast<void*>(b)); //it works (evil laugh)!
B*B;
A*a1=静态铸件(b)//编译错误
A*a2=静态施法(静态施法(b))//它有效(邪恶的笑声)!

但这违反了规则。如果您确实需要,只需使用
重新解释\u cast

您的问题实际上有两个部分:

  • 我是否应该使用
    static\u cast
    reinterpret\u cast
    来处理指向对象底层位模式的指针,而不考虑对象类型
  • 如果我应该使用
    reinterpret\u cast
    void*
    还是
    char*
    更适合处理这个底层位模式
  • :使用隐式转换和用户定义转换的组合在类型之间进行转换

    事实上,在5.2.9[expr.static.cast]13中,标准给出了以下示例:

    T* p1 = new T;
    const T* p2 = static_cast<const T*>(static_cast<void*>(p1));
    
    T*p1=新的T;
    常数T*p2=静态施法(静态施法(p1));
    
    它利用隐式强制转换:

    指向任何(可选cv限定)对象类型
    T
    的prvalue指针可以转换为指向(相同cv限定)
    void
    的prvalue指针。结果指针表示与原始指针值相同的内存位置。如果原始指针是空指针值,则结果是目标类型的空指针值

    但是,从
    T
    类型的指针到
    char*
    类型的指针没有隐式转换。因此,完成该转换的唯一方法是使用
    重新解释\u cast

    :通过重新解释基础位模式在类型之间转换

    因此,在回答问题的1部分时,当您转换为
    void*
    char*
    时,您希望使用底层位模式,应该使用
    reinterpret\u cast
    ,因为它的使用向读者表示与底层位模式的转换。

    接下来,让我们将
    void*
    char*
    进行比较。这两者之间的决定可能更依赖于应用程序。如果要对基础位模式使用标准库函数,只需使用函数接受的类型:

    • void*
      用于
      cstring
      库中提供的
      mem
      函数中
    • 并使用
      char*
      作为输入
    值得注意的是,C++专用库更倾向于<代码> char */COD>指向内存。
    将内存保持为
    void*
    似乎是出于兼容性原因而保留为指针out。因此,如果在您的基础位PATEN上不使用<代码> cSoS/<代码>库函数,请使用C++特定库行为来回答您的问题的<强> 2 :<强> >代码> char *<代码> >代码> Vult*/Cuff> < <强> >/P> < P>您的问题实际上有2个部分:

  • 我是否应该使用
    static\u cast
    reinterpret\u cast
    来处理指向对象底层位模式的指针,而不考虑对象类型
  • 如果我应该使用
    reinterpret\u cast
    void*
    还是
    char*
    更适合处理这个底层位模式
  • :使用隐式转换和用户定义转换的组合在类型之间进行转换

    事实上,在5.2.9[expr.static.cast]13中,标准给出了以下示例:

    T* p1 = new T;
    const T* p2 = static_cast<const T*>(static_cast<void*>(p1));
    
    T*p1=新的T;
    常数T*p2=静态施法(静态施法(p1));
    
    它利用隐式强制转换:

    指向任何(可选cv限定)对象类型
    T
    的prvalue指针可以转换为指向(相同cv限定)
    void
    的prvalue指针。结果指针表示与原始指针值相同的内存位置。