Re: [問題] overload 加上 namespace 之後會 fail

看板C_and_CPP作者 (inevitable......)時間9年前 (2014/07/31 19:38), 編輯推噓2(200)
留言2則, 2人參與, 最新討論串2/2 (看更多)
以下是個人的解釋不知道對不對 spec: N3485 14.6/p9 When looking for the declaration of a name used in a template definition, ... The lookup of names dependent on the template parameters is postponed until the actual template argument is known 14.6.2/p1 In an expression of the form: postfix-expression ( expression-list) where the postfix-expression is an unqualified-id, the unqualified-id denotes a dependent name if — any of the expressions in the expression-list is a pack expansion , — any of the expressions in the expression-list is a type-dependent expression, or — if the unqualified-id is a template-id in which any of the template arguments depends on a template parameter. If an operand of an operator is a type-dependent expression, the operator also denotes a dependent name. Such names are unbound and are looked up at the point of the template instantiation (14.6.4.1) in both the context of the template definition and ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the context of the point of instantiation. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 14.6.4.1/p1 For a function template specialization, ... if the specialization is implicitly instantiated because it is referenced from within another template specialization and the context from which it is referenced depends on a template parameter, the point of instantiation of the specialization is the point of instantiation of the enclosing specialization. Otherwise, the point of instantiation for such a specialization immediately follows the namespace scope declaration or definition that refers to the specialization. 首先 base case定義於general case之後 因此, 不論有沒有加namespace, 想在the context of the template definition中找到base case是不可能的 同時 _set_nth_element的general case永遠找的到自己 所以問題在於 為什麼沒加namespace的時候 就能在 the context of the point of instantiation中找的到base case 以下將point of instantiation簡寫為POI 沒有namespace的時候 apply 14.6.4.1得到 main -> set_nth_element<7> -> POI在set_nth_element之後 _set_nth_element<0> -> POI在set_nth_element之後 _set_nth_element<1> -> ... _set_nth_element<7> POI在set_nth_element之後 既然POI在set_nth_element之後 就能找到_set_nth_element的base case 加了namespace之後 雖然POI在set_nth_element之後 但_set_nth_element的general還是無法找到處於detail中的base case 如果在set_nth_element的definition之前加上 using detail::_set_nth_element; 就可以正常編譯了 以上看起來好像很順 但其實有問題 14.6.4.2 Candidate functions [temp.dep.candidate] For a function call where the postfix-expression is a dependent name, the candidate functions are found using the usual lookup rules (3.4.1, 3.4.2) except that: — For the part of the lookup using unqualified name lookup (3.4.1), only function declarations from the template definition context are found. — For the part of the lookup using associated namespaces (3.4.2), only function declarations found in either the template definition context or the template instantiation context are found 事實上 要在instantiation context中進行lookup 必須透過Argument Dependent Lookup 那麼 _set_nth_element<CUR_IDX+1>( p, f, std::integral_constant<int, LeftDistance::value-1>() ); 的argument中, p是fundamental type沒有associated namespace std::integral_constant的associated namespace就是std所以也連不到global namespace f呢? f是個lambda expression產生的closure object closure object依照spec來說是個local class 本不應該有associated namespace 所以照理來說原本的程式就算不加namespace detail也不應該能編譯 (因為general case還是應該找不到base case) 應該一番google 看起來似乎是g++的bug: https://groups.google.com/a/isocpp.org/forum/#!topic/std-proposals/6Mp0OUawJ8M "It appears that g++ includes the enclosing namespaces as associated namespaces for local classes, contrary to the current rules in the standard." 所以我把你原本的程式(沒有detail namespace)用clang 3.4.1去編: http://gcc.godbolt.org/ 一樣會有類似的錯誤 note: in instantiation of function template specialization '_set_nth_element<254, int *, <lambda at /tmp/gcc-explorer-compiler114631-16727-xtob8u/example.cpp:65:31>, std::integral_constant<int, -247> >' requested here 請注意上面的254跟-247 一樣代表展開時沒找到base case 以上推導不知道對不對 -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 220.129.1.231 ※ 文章網址: http://www.ptt.cc/bbs/C_and_CPP/M.1406806720.A.10B.html

08/02 11:45, , 1F
感謝大大熱心專業的回覆~~
08/02 11:45, 1F

08/13 07:09, , 2F
太專業了 @_@ 頭有點痛
08/13 07:09, 2F
文章代碼(AID): #1JsYh04B (C_and_CPP)
文章代碼(AID): #1JsYh04B (C_and_CPP)