看板 C_and_CPP 關於我們 聯絡資訊
呃我又來問問題了...... 開發平台(Platform): (Ex: VC++, GCC, Linux, ...) gcc version 4.8.2 (Ubuntu 4.8.2-19ubuntu1) 有用到 C++11,不過應該跟 C++11 沒關 問題(Question): 加上 namespace 之後 compiler 會到達編譯 template 深度上限 不過我想問的是為什麼不加的時候不會(見下面程式碼) 我有上網找過資料了,有一些類似的情形 可是好像又不太一樣 餵入的資料(Input): N/A 預期的正確結果(Expected Output): 加不加 namespace 都一樣(見下面程式碼) 錯誤結果(Wrong Output): 如問題描述 使用 g++ -ftemplate-depth=15 -std=c++11 編譯可通過 加上 -DMAKE_FAIL (放入 namespace 的使用)之後就會炸掉 程式碼(Code):(請善用置底文網頁, 記得排版) http://pastebin.com/nAwHMeCr 黃色是加上 namespace 的時候用 1 #include <type_traits> 2 #include <iostream> 3 如果用 namespace 包起來 就不能編譯 4 #ifdef MAKE_FAIL 5 namespace detail { 6 #endif 7 這個 template 編譯期遞迴呼叫自己 在沒有 namespace 的時候可以動 不過我覺得不加 namespace 的時候能編譯才是詭異的狀況 因為他可以用 template 自己本身實現下一層遞迴 所以進編譯期的無窮迴圈才是合理 8 template< 9 int CUR_IDX, 10 class PtrType, 11 class Func, 12 class LeftDistance 13 > 14 void _set_nth_element( 15 PtrType p, 16 Func f, 17 LeftDistance 18 ) 19 { 20 _set_nth_element<CUR_IDX+1>( p, f 直接傳下去 21 p, f, 把剩多遠傳下去,如果剩下 0 會 match 下面那個 template 22 std::integral_constant<int, LeftDistance::value-1>() 23 ); 24 } 25 用 overload 宣告上面那個函數遞迴尾端的 case integral_constant 0 的 時候就會 match 26 template< 27 int CUR_IDX, 28 class PtrType, 29 class Func 30 > 31 void _set_nth_element( 32 PtrType p, 33 Func f, 34 std::integral_constant<int, 0> 35 ) 36 { 37 f(p+CUR_IDX); 38 } 39 40 #ifdef MAKE_FAIL 41 } 42 #endif 43 理論上等價於 f(p+N),N 為編譯期常數 透過呼叫 _set_element_nth 來達成 44 template< 45 int N, 46 class PtrType, 47 class Func 48 > 49 void set_nth_element( 50 PtrType p, 51 Func f 52 ) 53 { 54 #ifdef MAKE_FAIL 55 using namespace detail; 56 #endif 57 _set_nth_element<0>(p, f, std::integral_constant<int, N>()); 58 } 59 60 int main(int argc, char const* argv[]) 61 { 62 int p[10] = {}; 63 64 std::cout << p[7] << std::endl; 65 set_nth_element<7>(p, [] (int *p) -> void { 66 *p = 100; 67 }); 68 std::cout << p[7] << std::endl; 69 return 0; 70 } -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 140.112.48.126 ※ 文章網址: http://www.ptt.cc/bbs/C_and_CPP/M.1406791393.A.EA0.html
carylorrk:看得痛苦 程式可以分開來貼在 ideone 嗎... 07/31 15:31
carylorrk:未看先猜會不會加了 namespace 找不到特化的 baseline? 07/31 15:32
johnjohnlin:我有貼程式碼連結在上面 07/31 15:37
johnjohnlin:為什麼會找不到特化,不是在同一個 namespace 下面? 07/31 15:38
johnjohnlin:應該是問為什麼加了 namespace 之後能找到的就不一樣 07/31 15:43
jackace:不加namespace: instantialize的時候在global中展開, 兩個 07/31 15:56
jackace:先忘記我上面說的好了 spec裡面有寫到 07/31 16:09
jackace:算了回文好了 07/31 16:09