Re: 請問一個關於iterator的問題...
看板C_and_CPP (C/C++)作者khoguan (Khoguan Phuann)時間19年前 (2005/08/08 20:14)推噓0(0推 0噓 0→)留言0則, 0人參與討論串3/3 (看更多)
※ 引述《freaky (jon)》之銘言:
: 事實上這牽涉到 C++ Standard 裡的一個目前處於草案階段的議題
: (415. Template deduction does not cause instantiation),
: 也就是規定不需要在 template deduction 過程中做具現化的動作。
: 提案人 John Spicer 認為要 compiler 在 template argument deduction
: 過程中去進行伺機具現化 (speculative instantiations) 是不合理的,
: 而他所取用的例子剛好就是 function template "std::distance<>()"。
: 不過他認為正因為這個例子並不在 deduction failure 所列舉的情況之中,
: compiler 應該回報錯誤。
: 之後另外一個草案
: (488. Local types, overload resolution, and template argument deduction)
: 就如何處理這個問題提出了三種解決辦法。一是在 overload resolution 時產生
: 錯誤。方法二是在 type-deduction 時產生錯誤。方法三是除非 overload
: resolution 的結果需要用到這個無法 instantiate 的 instance,否則不會產生
: 錯誤。最近一次的開會 (2005年四月) 討論傾向採用第二種方法。
是的,這兩個 core language issues 我也注意到了。
但為了避免治絲益棼,所以未提。 :-)
issue #415 和這裡的例子可說並無差別,不過 #488 則有點出入,
http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#488
它是特別針對 "instantiating a function (template) declaration with
a local type as a template type-parameter" 到底該怎麼處理而發。
^^^^^^^^^^^^
: ※ 引述《khoguan (Khoguan Phuann)》之銘言:
: ...略。
: : 真正的問題點並不發生在這個決定要選哪一個函式(也就是
: : overload resolution)的時間點上,而是在更早之前。也就
: : 是編譯過程根本就還沒進行到 overload resolution的階段
: : 就出錯了。
: ...略。
: : 所以除了原po定義的那個 global scope distance() 以外,
: : 編譯器還會去找到 std namespace 中的 distance(), 因為
: : 原po在呼叫 distance 時,所給的參數是 vector<int> 而
: : vector 又是宣告於 std namespace 中,所以被直接或間接
: : include 進來的 std namespace中所有的函式名稱,只要叫
: : 做 distance() 都會被找到。因為找到的 distance() 是個
: : function template, 所以要先做 template argument deduction
: : 推導成功後,才會將產生的 template instantiation 加到
: : candidate functions set中,準備進一步做 overload
: : resolution.
: ...略。
: : 編譯器需要確定這個東西到底是不是有效的 type, 如果最終的結果
: : 是無效的 type 那麼 template argument deduction 就失敗,這個
: : 函式就不會加入 candidate functions set中,這種「失敗」並不會
: : 產生編譯錯誤。
: : 問題是為了確定它有沒有效,編譯器必須先做一個動作,就是用
: : vector<int> 來 instantiate iterator_traits<> 這個 class template,
: : 然後再看產生的 class 中有沒有宣告 differenct_type 這個型別。
: ...以下略。
: 看來目前 gcc 和 EDG-based compiler 的處理方式比較接近方法二,
: VC.net 2003 則用了第三種方法,也就是本例不會發生編譯錯誤。
嗯,GCC, Comeau (on-line), VC. Net 2003 這三種環境
我都試過的。它們都會產生編譯錯誤,都是「抱怨」說 vector<int>
並未提供 iterator_category 這種 type.
方法二,所謂的 "Treat this as a type-deduction failure"
如果真是這樣處理的話,那反而可以通過編譯。因為 type-deduction
failure 就會導致那個函式版本被排除在 overload set 之外,
不會有編譯錯誤,即是所謂的 SFINAE. 當然,如果最後找不
到任何符合的函式版本,就會有編譯錯誤,不過,那是「後話」了 ^_^
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 61.227.252.32
討論串 (同標題文章)
完整討論串 (本文為第 3 之 3 篇):
C_and_CPP 近期熱門文章
PTT數位生活區 即時熱門文章
-4
30