簡體   English   中英

為什么std :: array沒有運算符T *?

[英]Why does std::array not have an operator T*?

對於C數組,通常情況下,簡單地命名數組與寫&foo[0]差不多有50年的歷史。

在我正在處理的項目中,從C樣式數組轉換為std :: array <>時,出現的絕大多數“錯誤”是由於C數組的上述特性引起的。

在所有情況下,解決方案都是微不足道的,只需追加.data() 但是我想到精心設計的operator T*應該直接解決這個問題。

有任何技術原因無法創建此運算符?

C樣式數組是按大小構造的。 您可以通過各種方式獲得數組的編譯時大小。 但是,當數組衰減為指針時,您將失去編譯時大小調整信息。 即使參數是“數組”類型,它實際上仍然只是沒有大小信息的指針。 如果數組作為函數參數傳遞( template<size_t S> void func(T(&param)[S]) ),則可以使用模板編程來保留大小。

許多C ++程序員認為數組到指針的隱式衰減是C樣式數組中的設計缺陷 確實,有損轉換很可能不是應該隱含的轉換,這並非不合理。 鑒於std::array試圖修復盡可能多的C樣式數組的缺陷,使其隱式衰減為指針將適得其反。

相比之下, C ++ 20的std::span類型提供了從std::array (以及C型數組等)的隱式轉換。 原因是這樣的轉換保留了信息:指針以及大小。 實際上,轉換甚至可以保留該大小的編譯時性質。


有任何技術原因無法創建此運算符?

無法 ”? 沒有。

引入data()使其在多個STL容器中具有相似的接口。 例如,std :: string和std :: vector也提供data(),它提供了實際數據緩沖區的地址。 因此,std :: array接口旨在匹配該接口。 您建議的Operator()是完全不同的方式,並且似乎並非絕對合適。 正如上面的評論者還提到的那樣,更合適的是運算符T *(),但這仍然不是STL設計人員喜歡的方式-他們引入了data()。 為什么? 也許是因為它更具可讀性。

有什么充分的理由不存在該運算符?

如果您要說為什么沒有operator T*()自動提供轉換,則(多個)潛在原因之一就是自動轉換的想法。

使用std::array的代碼通過利用operator T*()正確地編譯可能會很方便,而您卻可以使用沒有錯誤構建的程序。 但是,這有一些含義:

1)對operator T*() )的調用是程序員可能不希望看到的潛在運行時成本,而只是隨之而來。 在C ++中,目標是僅支付所需的費用,而強制轉換運算符只是強加自己就違背了這一想法。

2)由於程序員不了解的用法, operator T*()和強制轉換操作符通常可能會隱藏正在運行的代碼中的錯誤或瓶頸。

以我的經驗,請問一個代碼基礎上滿是強制轉換運算符的程序員,實際上實際上正在調用什么函數,而且不止一次,他們不確定他們的代碼采用了什么路徑,或者只是犯錯了(而且不要直到他們參加調試會話並看到被看似無辜的轉換操作員正在做的所有曲折之前,才意識到這一點。

因此,對於程序員來說,顯式地希望通過調用諸如data()類的函數而不是利用他們可能沒有意識到的operator T*()來“轉換”數據,要安全得多。

調用data()是您應避免的事情。 擁有這種功能可能會很有用(例如,在我們的示例中,遷移代碼或優化代碼處理內臟),但是它有悖於安全網std::array提供的安全性。

 std::array<int, 2> a{1,2};
 auto* ptr = a.data();
 std::cout << ptr[2]; // boom

剝奪安全網的事物應該是明確的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM