c++ - c++ - 如何正确重载运算符以从 __generic_buffer 执行隐式类型转换到 __generic_buffer?
问题描述
简单地说,我有以下代码:
template<typename p>
requires(std::is_pointer<p>::value)
struct __generic_buffer
{
p baseptr;
size_t size;
// member functions go here
};
using buffer = __generic_buffer<void*>;
using const_buffer = __generic_buffer<const void*>;
我希望能够写出这样的东西:
uint8_t arr[64];
buffer b {arr, 64};
const_buffer cb = b;
所以基本上我希望buffer
指向可修改的内存区域可以自由转换为const_buffer
指向常量内存区域,但不是相反,指针的行为方式。此外,我更希望这种转换与 . 的任何其他实例一起使用,__generic_buffer
例如.__generic_buffer<int*>
__generic_buffer<const int*>
解决方案
第一件事。__
C++ 标准为您的编译器和标准库保留其中包含的类型。在程序中使用它们会使您的程序格式错误,不需要诊断。(同样,_T
以一个开头_
,然后是一个大写字母)。
这种坏习惯来自于抄袭std
标头之类的编码风格。他们被允许这样做,而且实际上必须这样做,因为如果他们调用了某些东西bob
,那么有人可以合法地#define bob alice
破坏头文件。
有两种方法可以做你想做的事。
其中一个涉及编写转换构造函数,另一个涉及转换运算符。
我将展示操作员的方式。
template<class P>
requires(std::is_pointer<P>::value)
struct generic_buffer
{
P baseptr;
size_t size;
template<class U>
requires(std::is_same<std::remove_cv_t<std::remove_pointer_t<U>>, std::remove_pointer_t<P>>::value)
operator generic_buffer<U>() const {
return {baseptr, size};
}
// member functions go here
};
我可能会写一个特征而不是requires
内联,但基本上我们检查是否与删除and from之后*U
的类型相同。*P
const
volatile
*U
如果是这样,我们允许这个转换运算符存在。
在内部,我们使用隐式转换来转换指针类型。
现在,这并不完美,因为我们真的想检查删除 const、volatile 或两者中的任何一个是否会使其匹配。您可能想要编写一个执行该测试的类型函数。
构造方法就是上面的,但是倒过来了。声明构造函数对自动构造函数和类型的琐碎性有一些影响,而像这样的运算符则没有,因此为了避免不得不脱离这些问题,我将其实现为运算符。
推荐阅读
- laravel - Laravel belongs to Many relations
- javascript - 如何在 JavaScript 上使用 Google 日历 API 添加与会者
- r - 如何创建一个随 R 中迭代次数而变化的输入字符串?
- javascript - React:如何使用 onClick 运行背景动画?
- android - 以编程方式将 TextureView 与 ExoPlayer 一起使用?
- javascript - 在 BigCommerce 中通过 API 请求获取所有产品
- python - 如何放大图像的某些部分?
- php - 将 Magento 版本 2.4.1 降级到 1.9.4?需要完整的步骤
- javascript - 将资产包含在带有 Expo 的单声道包中,而不是相对路径?
- r - 如何通过矩阵中的周围单元格值替换一个单元格(R)