2014-12-01 48 views
0

說我們有這樣的簽名:C++強制轉換爲指向相同大小類型的指針?

void frobnicate(const uint8_t* raw_memory, size_t bytes); 

是否可以寫一個C++鑄造功能,這將允許鑄造任意類型(比如,例如,uint_least8_tsigned char,...)到uint8_t*養活進入該功能?

所有的標準報價是reinterpret_cast,這當然會從任何指針類型轉換。

例如:

std::vector<int> iv = ...; 
std::vector<char> cv = ...; 

frobnicate(sized_ptr_cast<const uint8_t*>(iv.data()), iv.size()); // must not compile 
frobnicate(sized_ptr_cast<const uint8_t*>(cv.data()), cv.size()); // should compile 

基本上與一些約束的reinterpret_cast

免責聲明:

  • 撇開f(T*, size_t len)是否是一個好的界面和基於迭代器接口將如何變得更好等
  • 沒有void*請:-)
  • (?)
  • CHAR_BIT == 8
+4

寫一個函數包裝reinterpret_cast static_assert/enable_if – 2014-12-01 21:25:42

+0

@BryanChen:只是一個'sizeof'檢查在'static_assert'然後? – 2014-12-01 21:27:58

+0

取決於你想要它的通用性。想到''const','volatile','alignof'。 – 2014-12-01 21:36:22

回答

3

她e是那個包裹reinterpret_caststatic_assert

template <typename T, typename U> 
T sized_ptr_cast(U *p) { 
    static_assert(std::is_pointer<T>::value, ""); 
    static_assert(sizeof(typename std::remove_pointer<T>::type) == sizeof(U), "size must be same"); 
    return reinterpret_cast<T>(p); 
} 

http://coliru.stacked-crooked.com/a/d13da2471b051d5d

+0

爲什麼不採取'T *'和'U *'並刪除'is_pointer'和'remove_pointer'? – 2014-12-01 21:53:17

+0

@ T.C。只是因爲它使用它像'sized_ptr_cast '而不是'sized_ptr_cast ' – 2014-12-01 21:55:18

+0

好吧,'U'仍然可以修復。 – 2014-12-01 21:55:41

2

一個簡單的模板功能做你問約束它,使用std::pointer_traits的實現:

template<class T, class P> auto sized_ptr_cast(P&& p) 
-> typename std::enable_if<sizeof(std::pointer_traits<T>::element_type) 
    == sizeof(std::pointer_traits<P>::element_type), T>::type 
{ return reinterpret_cast<T>(p); } 

優勢利用static_assert:用途SFINAE
缺點:更詳細的診斷信息