看板 C_and_CPP 關於我們 聯絡資訊
最近寫個東西,遇到一個需求, template < typename IterType > class Foo { typename ??? ValueType ; } ; 就是我希望當使用者 class Foo<int*> 的話, class Foo<int*>::ValueType 要是 int ; 我希望編譯器可以幫我導出 IterType 解參照(dereference)之後的型別。 想了一下我還真想不到怎麼寫 -_-|| 如果說 IterType 一定都是指標的話,那事情還好辦, 我可以透過特化得到 ValueType, template < typename ValueType > class Foo < ValueType* > { ... } ; 但是 IterType 也可能是有覆載 operator* 的自定型別, 這種特化就抓不到了。 想了一下可能可以使用 c++0x 的 decltype 來幫忙, 於是嘗試了一下以下寫法: template < typename IterType > class Foo { typedef decltype (*IterType) ValueType ; } ; 編譯器報錯,說 decltype 裡面必須是個 expression, 而 *IterType 並不是 expression。 又嘗試了 template < typename IterType > class Foo { IterType i ; typedef decltype (*i) ValueType ; } ; 成功了,但是這樣我的 class 就多了一個我不要的 IterType 物件。 而且感覺很智障,想了一下,可以把這個東西抽離。 變成這樣 template < typename T > struct dereference { T v ; typedef decltype(*v) type ; } ; template < typename IterType > class Foo { IterType i ; typedef dereference<IterType>::type ValueType ; } ; 這樣就 Foo 看起來就聰明多了,而我反正根本不會去具現化 dereference, 所以也不會有什麼 T 真的生出來,但是這個寫法還是有問題, 因為 T 可能沒有 public default constructor。編譯便不會過。 又想了一下,最後改成 template < typename T > struct dereference { T dummy() ; typedef decltype(*dummy()) type ; } ; template < typename IterType > class Foo { IterType i ; typedef dereference<IterType>::type ValueType ; } ; 搞不好大家早就知道更簡單的做法了 -_- 我自己發明輪胎, 只是我 Google 找不到 Orz -- To iterate is human, to recurse, divine. 遞迴只應天上有, 凡人該當用迴圈.   L. Peter Deutsch -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 118.160.114.69
loveme00835:typedef decltype(**(IterType*)0) ValueType; 12/31 02:52
loveme00835:dummy() 那邊少了 static 喔 12/31 02:52
DirkC:這出來都會是reference型別吧..? 例如int&,而非int 12/31 10:57
DirkC:因為最外圈加上*出來是lvalue 12/31 10:57
DirkC:但是要出來是rvalue的結果又要依賴運算子重載.. 12/31 11:00
DirkC:似乎一開始設計上就反過來思考會順暢許多,例如一開始就<int> 12/31 11:02
DirkC:另外想單純推這篇文章,有啟發性的分享 :) 12/31 11:03
james732:推這篇文章 12/31 11:05
loveme00835:本來也是想推traits, 不過只是想找更簡短的方法, int& 12/31 14:26
loveme00835:倒是沒有什麼問題, 不過遇到 cv-qualirs 就炸了 XDD 12/31 14:27
loveme00835:疑不對, 我測錯 = __ = 12/31 19:44
VictorTom:看不懂推~~~~XD 01/01 11:01
Bencrie:這讓我確信我不會 C++ 了 XD 01/01 16:19
VictorTom:小弟我很早就知道我不懂C++了....Orz 01/02 00:02