【问题标题】:static_cast throws error but C-style cast worksstatic_cast 抛出错误,但 C 风格的演员可以工作
【发布时间】:2017-09-15 10:41:27
【问题描述】:

当我使用static_cast:

const C* cObj; // C is a user-defined class
void* obj = static_cast<void*>(cObj);

我得到错误:

转化失去限定词

但是当我使用 C 风格的演员表时,它可以工作:

const C* cObj;
void* obj = (void*)cObj;

为什么会这样?

通过 C++ 样式转换的正确方法是什么?

【问题讨论】:

  • 你做错了,你应该转换为const void*(当然obj也应该是那种类型)。你不能用static_cast 抛弃const
  • C 风格的演员表就像一把大锤;如果可以的话,程序员需要知道后果。如果您不确定,那么在您阅读它们之前,切勿使用 C 样式转换或 reintepret_cast,起点是:en.cppreference.com/w/cpp/language/explicit_cast
  • @Someprogrammerdude 如果我真的想删除constness 怎么办?我应该改用const_cast&lt;&gt; 吗?
  • 我并不是说这是一个好主意(通常不是),但是是的,这是抛弃const 的唯一方法。不过,您可能需要两种类型转换,一种用于 const,另一种用于类型。
  • 话虽如此,您要解决的实际问题是什么?你为什么做这个?在不告诉我们应该解决什么的情况下寻求解决方案的帮助称为the XY problem。也许如果您询问实际问题,我们可以帮助您解决它,而无需抛弃const

标签: c++ casting static-cast


【解决方案1】:

为什么会这样?

C 风格的转换之所以有效,是因为它结合了多个 C++ 转换的强大功能。例如,它可以抛弃 const-ness 并同时重新解释指针类型。 C++ 编译器用来决定如何解释特定 C 转换的过程在 here 中进行了描述。

C++ 转换常量指针的方法是将其转换为另一个常量指针,如下所示:

const void* obj = static_cast<const void*>(cObj);

如果你还需要抛弃 const-ness,你可以像这样链接强制类型转换:

void* obj = const_cast<void*>(static_cast<const void*>(cObj));

const_cast 的常规预防措施照常适用:如果您要转换的指针指向一个常量对象,则在转换后通过非常量指针修改该对象会导致未定义的行为。

【讨论】:

    【解决方案2】:

    如果通往毁灭之路真的是你的意图......

    struct C;
    
    template<class T>
    T* daringly_remove_const_and_damn_the_consequences(T const* p)
    {
        return const_cast<T*>(p);
    }
    
    const C* cObj; // C is a user-defined class
    void* obj = static_cast<void*>(daringly_remove_const_and_damn_the_consequences(cObj));
    

    【讨论】:

      猜你喜欢
      • 2012-08-14
      • 1970-01-01
      • 2019-03-25
      • 1970-01-01
      • 1970-01-01
      • 2015-05-16
      • 1970-01-01
      • 2014-11-29
      • 1970-01-01
      相关资源
      最近更新 更多