作者johnjohnlin (LYSin8)
看板C_and_CPP
標題[問題] overload 加上 namespace 之後會 fail
時間Thu Jul 31 15:23:09 2014
呃我又來問問題了......
開發平台(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