繁体   English   中英

c ++ - 如何正确重载运算符以从 __generic_buffer 进行隐式类型转换<void*>到 __generic_buffer<const void*> ?

[英]c++ - how to properly overload operator to do implicit type cast from __generic_buffer<void*> to __generic_buffer<const void*>?

简单来说,我有以下代码:

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 ,例如__generic_buffer<int*>__generic_buffer<const int*>

先说第一件事。 带有__类型由 C++ 标准为您的编译器和标准库保留。 在程序中使用它们会使您的程序格式错误,无需诊断。 (另外, _T_开头,然后是大写字母)。

这种坏习惯来自于复制std headers之类的编码风格。 他们被允许这样做,实际上必须这样做,因为如果他们调用了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
};

我可能会写一个 trait 而不是这样做requires内联,但基本上我们在从*U删除constvolatile后检查*U是否与*P类型相同。

如果是这样,我们允许这个转换运算符存在。

在里面,我们使用隐式转换来转换指针类型。

现在,这并不完美,因为我们真的想检查删除 const、volatile 或两者中的任何一个是否会使其匹配。 您可能想要编写一个执行该测试的类型函数。

构造器的方式就是上面的,但是倒退了。 声明构造函数对自动构造函数和类型的琐碎性有一些影响,而像这样的运算符则没有,因此为了避免离题,我将其实现为运算符。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM