【问题标题】:const_cast with two levels pointers带有两级指针的 const_cast
【发布时间】:2014-12-09 18:43:39
【问题描述】:

我想使用 C++ 格式进行这种转换,它以 C 方式工作。但是当我尝试 C++ 格式时它失败了。

有效!

void req_password(const void *data, size_t datalen)
{
    char *password_old = ((char **) data)[0];
    char *password_new = ((char **) data)[1];
    ...
}

失败了

void req_password(const void *data, size_t datalen)
{
    char *password_old = (const_cast<char **>(data))[0];
    char *password_old = (const_cast<char **>(data))[1];
    ...
}

错误:

error: invalid const_cast from type 'const void*' to type 'char**'

所以我的疑问是,我如何使用 C++ 方式进行这种转换?

PS:这段代码是API的一部分,我无法控制数据的输入。

【问题讨论】:

  • 这是我收到的输入格式,我无法更改输入参数的格式。
  • 抱歉,我更正了。
  • 您需要先将const_cast 移出const,然后将reinterpret_cast 移至char **。但这是我一段时间以来在 SO 上看到的最丑陋的代码。
  • 因为谷歌指南风格的规则。
  • 看起来你有一个糟糕的 API 可以使用,所以我想你也应该遵循一个糟糕的风格指南。

标签: c++ casting const-cast


【解决方案1】:

不要。

如果你得到的是不可变的数据,那么你得到的是不可变的数据,这就是它的结束!

首先,这是我为最大安全性提出的建议。将data 强制转换为它的真实类型有点棘手,唉:

void req_password(const void* data, size_t datalen)
{
    const char* password_old = (reinterpret_cast<const char* const*>(data)[0]);
    const char* password_new = (reinterpret_cast<const char* const*>(data)[1]);
    // ...
}

(实际上我在上面添加了一些constness,因为这似乎是首先拥有const void*的意图。)

但是,如果您真的希望字符串是可变的,那么这也可以:

void req_password(const void* data, size_t datalen)
{
    char* password_old = (reinterpret_cast<char* const*>(data)[0]);
    char* password_new = (reinterpret_cast<char* const*>(data)[1]);
    // ...
    // More obvious when you recall that `const void*` is actually `void const*`;
    // So:
    //   void  const*
    // becomes:
    //   char* const*
}

请注意,您甚至 需要 const_cast 在这里,因为您没有修改 data 指向的东西:您取消引用它并获取它的指针。

当然,理想情况下,data 将指向一个 const std::string 实例。

【讨论】:

  • 应该是(reinterpret_cast&lt;const char* const*&gt;(data))[0]
  • @Alex:两者都可以。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-03
  • 2023-04-01
  • 1970-01-01
  • 2020-11-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多