如何将const uint8_t *转换为char *

时间:2018-08-01 18:40:18

标签: c++ casting

对于要使用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 ++样式的强制转换而不嵌套两个单独的强制转换操作?

4 个答案:

答案 0 :(得分:5)

  

有什么方法可以使用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));
}

答案 1 :(得分:4)

  

有什么方法可以使用C ++样式的强制转换而不嵌套两个单独的强制转换操作?

如果您希望像char* foo = some_cast(source)这样的一行中完成此操作,则否。唯一可以删除const的演员表是const_cast,因此您需要加上一个额外的演员表才能将现在的非const指针转换为源类型。那让你充满了怪物

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

作为单行解决方案。这是一项安全功能,因此很明显您要删除常量性。

答案 2 :(得分:2)

  

另一种选择是这种怪兽,我觉得这很不可读:

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

您可能会发现它不可读,但这是用C ++表示这种转换的理想方法。

重要的是:

  • 您正在使用C风格的API,无论出于何种原因,该API本身都不是const正确的,但是您想尽可能保留自己代码的const正确性,因此必须进行强制转换以删除cv -类型的限定条件。
  • C风格的API使用签名数据类型,而您的应用程序使用未签名数据类型。

总共,这是代码需要进行的两次转换-删除常量,并转换为带符号的类型。如果要遵循这些编码惯例,这要求您进行两次明确表示的转换。您可能不同意这个原则,但是您的公司/编码实践肯定会同意。

当然,我认为没有什么可以阻止您编写这样的内容:

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);

答案 3 :(得分:0)

  

有什么方法可以使用C ++样式的强制转换而无需嵌套两个单独的强制转换操作?

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

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