看板 C_and_CPP 關於我們 聯絡資訊
開發平台(Platform): (Ex: VC++, GCC, Linux, ...) Standard C++11 or beyond 問題(Question): 想要請各位大大,是否存在一種手法, 能讓我以 type 來 access data member? 會想要用 type 來存取,是因為我根據不同的 type 需要存取到不同的值, 但因為是 template,到底會有哪些 type 其實我不確定。 舉個例子來說 struct Foo { template <typename T> T& get() { static T v; return v; } } 這樣我就可以透過下面這種手法來「模擬」用 type 來存取 data member Foo a; a.get<int>() = 5; a.get<int>()++; std::cout << a.get<int>() << std::endl; // 印出 6 a.get<float>() = 3.14; std::cout << a.get<float>() << std::endl; // 印出 3.14 這個方法的缺點,是這些模擬出來的 data member 一定都是 static 的 因為當我 Foo a; Foo b; a.get<int>() = 5; std::cout << b.get<int>() << std::endl; // 印出 5 那我現在很想知道有沒有一種手法可以讓我同時滿足下面三個條件: 1. 可以透過 type 來自動的生成 data member 當然,會有哪些 type,在 compile time 就已經確定 但使用可以不用明確指定會有 int, float, Bar, 等等 要像上面那種例子一樣,compiler 要能自己蒐集所有的使用點 2. 要是 non-static 的! a.get<X>() 跟 b.get<X>() 要是不同人 3. 要有效率,希望能避開下面這種作法 struct Foo { template <typename T> T& get() { static std::map<Foo*, T> m; return m[this]; // 既然是 static,那我透過 this 來 map 可以吧 } }; 百思不得其解,盼前輩解惑。 小妹先謝過了。 -- To iterate is human, to recurse, divine. 遞迴只應天上有, 凡人該當用迴圈.   L. Peter Deutsch -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 219.71.74.248 ※ 文章網址: http://www.ptt.cc/bbs/C_and_CPP/M.1403554635.A.FD0.html
LPH66:似乎可以參考 std::get<type>(std::tuple) 的實作? 06/24 04:23
LPH66:唔, 仔細看才發現這要 C++14 之後才是標準 @@ 06/24 04:24
yoco315:get(tuple) 我會作,但這邊有點不一樣。get(tuple)的時候 06/24 04:32
yoco315:很明確知道tuple裡面的每一個型別,透過meta-programming 06/24 04:33
yoco315:可以遞迴的索引到正確的member,但我現在這個狀況是get 06/24 04:34
yoco315:沒有辦法知道到底有多少type嘗試具現這個函數,手上有的 06/24 04:34
yoco315:就只有自己一個 T 這個 type @@ 06/24 04:35
yoco315:剛試了一下 C++14 的 variable template,發現只能全域 06/24 04:35
yoco315:data member 不能是 template XD 06/24 04:36
worldlet:不能用 union 嗎 XD 06/24 08:39
descent:連語法都看不懂 06/24 09:45
azureblaze:寫工具掃所有用到a.get<T>()的地方建tuple(超大工程 06/24 09:55
azureblaze:要同時123應該一定得跑兩個phase? 06/24 10:01
yoco315:azureblaze,有想過,但可惜a.get<T>會在template裡面被呼叫 06/24 10:18
yoco315:而且是template裡面的template裡面的template裡面的.. 06/24 10:18
yoco315:除非我的工具很完整的支援 c++ template 型別推導,不然 qq 06/24 10:19
azureblaze:我覺得就是因為太複雜所以variable template不能這樣用 06/24 10:22
loveme00835:virtual function call 的 cost 可接受? 06/24 10:24
yoco315:我快要放棄了了 XD 最後可能會對 3 妥協 06/24 10:24
azureblaze:如果又把他extern或指標傳出去那還會更複雜 06/24 10:24
azureblaze:試了一下variant的寫法效率好像會更糟 06/24 10:27
azureblaze:http://ideone.com/MMPhYa 至少不用lock static? 06/24 10:54
yoco315:哇!好聰明的手法 XD 竟然用 static variable addr 當 key 06/24 11:12
yoco315:學起來,ㄎㄎ 06/24 11:13
carylorrk:所以一定要 runtime 來查嗎~? 06/24 12:36
kwpn:boost variant就是這個效果吧 06/24 12:39
loveme00835:我的解法 ideone.com/yzomRg 06/24 12:40
carylorrk:variant 不是類似 union 嗎?我有搞錯嗎XD? 06/24 12:53
carylorrk:版大神解~compile time 就定位的到了 06/24 12:55
azureblaze:union只吃POD 06/24 12:56
azureblaze:不過上面的作法非POD都會leak 還是得包層virtual 06/24 13:00
carylorrk:我的意思是 variant 像 union 無法依 type 存不同值吧? 06/24 13:05
carylorrk:不是很懂非 POD 會 leak 的意思@@ 可以請教一下嗎XD? 06/24 13:09
carylorrk:沒事 我知道了~ 06/24 13:16
yoco315:謝謝版主大大 ^^~* 好強... 06/24 13:58
loveme00835:@azure 那就會肥一點 xD http://ideone.com/Lh92EU 06/24 14:43
yoco315:我想也許可以直接放在 std::vector<boost::any> XD 06/24 14:49
suhorng:現在 union 不是也可以放 non-POD 嗎? 只是不好用... 06/24 14:50
loveme00835:lol 差點忘了 06/24 14:50
yoco315:不過我需要的是「不同型別,不同實體,同時存在」 06/24 15:41
yoco315:所以無法使用 union XD 06/24 15:42