簡體   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