【问题标题】:How to cast const uint8_t* to char*如何将 const uint8_t* 转换为 char*
【发布时间】:2019-01-09 10:25:55
【问题描述】:

我有一个 const uint8_t*,我想将它转换为一个 char*,以获得一个需要 char* 的接口。

最简单的方法是使用 C 风格的演员表:

const uint8_t* aptr = &some_buffer;
char* bptr = (char*)aptr;

但是,我们的内部样式指南(基于 Google C++ Style Guide)禁止 C 样式转换。

另一种选择是这个怪物,我觉得它很难读:

char *cptr = reinterpret_cast<char*>(const_cast<uint8_t*>(aptr));

我试过的这些其他选项都编译失败:

char* dptr = reinterpret_cast<char*>(aptr);
char* eptr = const_cast<char*>(aptr);
char* fptr = static_cast<char*>(aptr);

有没有什么方法可以使用 C++ 风格的转换来执行这种转换,而无需嵌套两个单独的转换操作?

【问题讨论】:

  • 除非您确定您的const uint8_t* 总是 指向一个非常量 缓冲区,否则这可能会导致未定义行为.
  • 然后你可以编写一个 const 正确的包装函数并向作者发送补丁:)
  • @SergeyA cppreference 不同意你的观点。您能否提供索赔的来源?它说“const_cast 可以形成一个引用或指向实际引用一个 const 对象的非 const 类型的指针”.
  • 有问题的 API 是 STL 的一部分 :( 我正在尝试做这个问题中的要求,但也从 uint8_t 转到 char:stackoverflow.com/questions/13059091/…
  • @KerrickStaley 请显示minimal reproducible example。标准库是完全正确的const。这意味着,如果您在任何时候认为需要 const_cast 来使用标准库功能,那么您在某个地方犯了一个大错误。

标签: c++ casting


【解决方案1】:

有什么方法可以使用 C++ 风格的转换来执行此转换,而无需嵌套两个单独的转换操作?

不便携,不。没有单一的“类型错误,const也错误”演员表。

另一种选择是这个怪物,我觉得它很难读:

char *cptr = reinterpret_cast<char*>(const_cast<uint8_t*>(ptr));

这样做。

C++ 演员表和你的内部风格指南都在努力让这看起来很可怕。

您可以通过编写自己的演员表来防止这些演员表的重复。

template< typename T >
char* awful_monster_cast( const T * ptr )
{
    return reinterpret_cast<char*>(const_cast<T*>(ptr));
}

【讨论】:

    【解决方案2】:

    有什么方法可以使用 C++ 风格的转换来执行此转换,而无需嵌套两个单独的转换操作?

    如果你想在像char* foo = some_cast(source) 这样的单行中完成它,那么不。唯一可以删除 const 的演员是 const_cast 所以你需要加上一个额外的演员来将现在的非 const 指针转换为你的源类型。剩下的就是怪物了

    char *cptr = reinterpret_cast<char*>(const_cast<uint8_t*>(aptr));
    

    作为单行解决方案。这是一项安全功能,因此很明显您正在删除 constness。

    【讨论】:

      【解决方案3】:

      另一种选择是这个怪物,我觉得它很难读:

      char *cptr = reinterpret_cast<char*>(const_cast<uint8_t*>(aptr));
      

      您可能会觉得它不可读,但这是在 C++ 中表达这种转换的惯用方式。

      以下是重要的:

      • 您正在使用 C 风格的 API,无论出于何种原因,它本身不是 const 正确的,但您希望尽可能地保留自己代码的 const 正确性,因此需要进行强制转换以删除 cv - 类型的限定。
      • C 风格的 API 使用有符号数据类型,而您的应用程序使用无符号数据类型。

      总的来说,这是您的代码需要进行的两种转换 - 删除 const 和转换为有符号类型。如果您想遵守这些编码实践,这要求您进行两次明确表达的转换。您可能不同意这一原则,但您的公司/编码实践肯定同意。

      当然,我认为没有什么能阻止你写这样的东西:

      char * convert_to_c_data_buffer(uint8_t const* ptr) {
          return reinterpret_cast<char*>(const_cast<uint8_t*>(ptr));
      }
      
      char* dptr = convert_to_c_data_buffer(aptr);
      

      【讨论】:

        【解决方案4】:

        有没有什么方法可以使用 C++ 风格的转换来执行此转换,而无需嵌套两个单独的转换操作?

        当然。无需嵌套这些强制转换操作。相反,您可以使用两个单独的表达式:

        auto cuint = const_cast<uint8_t*>(aptr);
        auto cptr  = reinterpret_cast<char*>(cuint);
        

        【讨论】:

          猜你喜欢
          • 2011-10-23
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-09-08
          • 2021-04-11
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多