如何将const uint8_t*强制转换为char*

5

我有一个 const uint8_t*,需要转换为一个接口期望的 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++风格的转换来执行此转换,而不必嵌套两个单独的转换操作?

1
没错,这是一个接口,它接受一个 char* 但实际上不会修改其内容(接口设计者本应添加一个 const,但我无法更改)。 - Kerrick Staley
3
然后你可以编写一个const正确的包装函数并向作者发送补丁 :) - Galik
2
@SergeyA cppreference不同意您的观点。您能提供一个支持您说法的来源吗?它说:“const_cast使得形成指向实际上是const对象的非const类型的引用或指针成为可能”。 - François Andrieux
1
所涉及的API是STL的一部分 :( 我正在尝试按照这个问题所要求的做,但同时也要从uint8_t转换为char:https://dev59.com/questions/NWcs5IYBdhLWcg3wMhCz - Kerrick Staley
2
@KerrickStaley 请提供一个 [MCVE]。标准库完全支持 const,这意味着如果您认为需要使用 const_cast 来使用标准库功能,则说明您在某个地方犯了一个大错误。 - François Andrieux
显示剩余10条评论
4个回答

8
有没有任何一种方法可以使用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));
}

5

Another option is this monstrosity, which I find pretty unreadable:

char *cptr = reinterpret_cast<char*>(const_cast<uint8_t*>(aptr));
您可能会觉得它很难懂,但这是C++里表达此转换的惯用方式。
以下是重点:
- 您正在使用一个C风格API,由于某些原因,它本身不是const-correct,但您希望尽可能地保留自己代码的const-correctness,这就需要进行强制类型转换来删除类型的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++风格的转换来执行此转换,而不需要嵌套两个单独的转换操作?
如果你想像char* foo = some_cast(source)这样一行代码完成,那么不行。唯一能够移除const的转换是const_cast,所以你需要它加上一个额外的转换将那个现在非常量指针转换为你的源类型。这会留下一个丑陋的代码。
char *cptr = reinterpret_cast<char*>(const_cast<uint8_t*>(aptr));

作为单行解决方案。这是一项安全功能,使得你删除const的行为非常明显。


0
有没有办法使用C++风格的转换来执行此转换,而不需要嵌套两个单独的转换操作?
当然可以。没有必要嵌套这些转换操作。相反,您可以使用两个单独的表达式:
auto cuint = const_cast<uint8_t*>(aptr);
auto cptr  = reinterpret_cast<char*>(cuint);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接