![](/img/trans.png)
[英]Why does Visual C++ warn on implicit cast from const void ** to void * in C, but not in C++?
[英]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
刪除const
和volatile
后檢查*U
是否與*P
類型相同。
如果是這樣,我們允許這個轉換運算符存在。
在里面,我們使用隱式轉換來轉換指針類型。
現在,這並不完美,因為我們真的想檢查刪除 const、volatile 或兩者中的任何一個是否會使其匹配。 您可能想要編寫一個執行該測試的類型函數。
構造器的方式就是上面的,但是倒退了。 聲明構造函數對自動構造函數和類型的瑣碎性有一些影響,而像這樣的運算符則沒有,因此為了避免離題,我將其實現為運算符。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.