鑑於std::copy
(爲了微不足道的類型顯然)只能實現一個包裝周圍memmove(*),我想知道:類型安全的memcpy C++包裝?
- 是否有你需要
memcpy
的次標準C++類型安全的包裝? (我無法計算我忘記乘以sizeof
的次數。) - 如果標準中沒有任何內容,是否有任何建議?如果不是,爲什麼不呢?
- 提供自動執行
sizeof
乘法的memcpy
包裝是否存在任何特定障礙?
(*):C++標準庫的實現(從後MSVC 2005()到現代MSVC2015,的libC++等!)衰變std::copy
TriviallyCopyable類型memmove
。 Bot 不是到memcpy
。這是因爲:
std::copy(src_first, src_last, destination_first)
定義:行爲是不確定如果
d_first
在該範圍內[first, last)
。- 只有開始在目標範圍內的時,必須在目標範圍內。目標範圍允許擴展到目標範圍。也就是說,
d_first
可以在源範圍的「左邊」,目標範圍可以擴展到源範圍。
- 只有開始在目標範圍內的時,必須在目標範圍內。目標範圍允許擴展到目標範圍。也就是說,
對於
std::memcpy
的定義是如果對象重疊,則操作是未定義的。
- 也就是說,全範圍不能重疊:這是允許的memcpy是最快的變種,因爲它可以只是假設源和目的地的記憶是完全脫離。
對於
std::memmove
,該定義是:對象可以重疊:複製發生如同字符被複制到一個臨時的字符數組,然後字符被從陣列複製到dest 。
- 即,源和目的地範圍可以任意地重疊,沒有任何限制。
鑑於此,很顯然,你可以使用std::memove
實現std::copy
爲TrivialllyCopyable類型,因爲的memmove不會強加任何限制,並派遣到正確的實現可以通過在類型編譯時完成特點 -
但很難在memcpy
方面實現std::copy
因爲(a)檢查指針範圍是否重疊將不得不在運行時做,和(b)甚至實現了不相關的運行時檢查內存範圍could be quite a mess。
因此,這給我們留下了
void* memcpy(void* dest, const void* src, std::size_t count);
功能與比恆星界面,在這裏你需要不斷繁殖的非字符對象的輸入計數與他們sizeof
,這是完全無類型。
但是memcpy是最快的(並且有很大的差距,你自己去衡量一下),並且當你需要TriviallyCopyable類型的快速拷貝時,你可以到達memcpy。這表面上應該很容易像一個類型安全的包裝來包裝:
template<typename T>
T* trivial_copy(T* dest, T* src, std::size_t n) {
return static_cast<T*>(std::memcpy(dest, src, sizeof(T) * n));
}
但後來,目前還不清楚無論您應該做的通過std::is_trival
編譯時檢查或諸如此類,當然可能會有一些討論是否去與確切的memcpy
簽名訂單,yadda yadda。
那麼我真的不得不重新發明這個輪子嗎?是否針對標準進行了討論?等
是什麼讓你'std :: copy'必須由'memmove'實現? – nwp
這種包裝的用例是什麼?爲什麼你不喜歡'std :: copy'本身? – Mikhail
你可能舉一個例子,你需要手動memcpy(甚至複製)嗎?在幾乎所有情況下,所有這些都是在後臺使用複製構造函數和副本分配完成的。 – luc