看板 C_and_CPP 關於我們 聯絡資訊
※ 引述《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