[問題] 非靜態,access by type 的 data member

看板C_and_CPP作者 (眠月)時間10年前 (2014/06/24 04:17), 編輯推噓7(7034)
留言41則, 9人參與, 最新討論串1/2 (看更多)
開發平台(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

06/24 04:23, , 1F
似乎可以參考 std::get<type>(std::tuple) 的實作?
06/24 04:23, 1F

06/24 04:24, , 2F
唔, 仔細看才發現這要 C++14 之後才是標準 @@
06/24 04:24, 2F

06/24 04:32, , 3F
get(tuple) 我會作,但這邊有點不一樣。get(tuple)的時候
06/24 04:32, 3F

06/24 04:33, , 4F
很明確知道tuple裡面的每一個型別,透過meta-programming
06/24 04:33, 4F

06/24 04:34, , 5F
可以遞迴的索引到正確的member,但我現在這個狀況是get
06/24 04:34, 5F

06/24 04:34, , 6F
沒有辦法知道到底有多少type嘗試具現這個函數,手上有的
06/24 04:34, 6F

06/24 04:35, , 7F
就只有自己一個 T 這個 type @@
06/24 04:35, 7F

06/24 04:35, , 8F
剛試了一下 C++14 的 variable template,發現只能全域
06/24 04:35, 8F

06/24 04:36, , 9F
data member 不能是 template XD
06/24 04:36, 9F

06/24 08:39, , 10F
不能用 union 嗎 XD
06/24 08:39, 10F

06/24 09:45, , 11F
連語法都看不懂
06/24 09:45, 11F

06/24 09:55, , 12F
寫工具掃所有用到a.get<T>()的地方建tuple(超大工程
06/24 09:55, 12F

06/24 10:01, , 13F
要同時123應該一定得跑兩個phase?
06/24 10:01, 13F

06/24 10:18, , 14F
azureblaze,有想過,但可惜a.get<T>會在template裡面被呼叫
06/24 10:18, 14F

06/24 10:18, , 15F
而且是template裡面的template裡面的template裡面的..
06/24 10:18, 15F

06/24 10:19, , 16F
除非我的工具很完整的支援 c++ template 型別推導,不然 qq
06/24 10:19, 16F

06/24 10:22, , 17F
我覺得就是因為太複雜所以variable template不能這樣用
06/24 10:22, 17F

06/24 10:24, , 18F
virtual function call 的 cost 可接受?
06/24 10:24, 18F

06/24 10:24, , 19F
我快要放棄了了 XD 最後可能會對 3 妥協
06/24 10:24, 19F

06/24 10:24, , 20F
如果又把他extern或指標傳出去那還會更複雜
06/24 10:24, 20F

06/24 10:27, , 21F
試了一下variant的寫法效率好像會更糟
06/24 10:27, 21F

06/24 10:54, , 22F
http://ideone.com/MMPhYa 至少不用lock static?
06/24 10:54, 22F

06/24 11:12, , 23F
哇!好聰明的手法 XD 竟然用 static variable addr 當 key
06/24 11:12, 23F

06/24 11:13, , 24F
學起來,ㄎㄎ
06/24 11:13, 24F

06/24 12:36, , 25F
所以一定要 runtime 來查嗎~?
06/24 12:36, 25F

06/24 12:39, , 26F
boost variant就是這個效果吧
06/24 12:39, 26F

06/24 12:40, , 27F
我的解法 ideone.com/yzomRg
06/24 12:40, 27F

06/24 12:53, , 28F
variant 不是類似 union 嗎?我有搞錯嗎XD?
06/24 12:53, 28F

06/24 12:55, , 29F
版大神解~compile time 就定位的到了
06/24 12:55, 29F

06/24 12:56, , 30F
union只吃POD
06/24 12:56, 30F

06/24 13:00, , 31F
不過上面的作法非POD都會leak 還是得包層virtual
06/24 13:00, 31F

06/24 13:05, , 32F
我的意思是 variant 像 union 無法依 type 存不同值吧?
06/24 13:05, 32F

06/24 13:09, , 33F
不是很懂非 POD 會 leak 的意思@@ 可以請教一下嗎XD?
06/24 13:09, 33F

06/24 13:16, , 34F
沒事 我知道了~
06/24 13:16, 34F

06/24 13:58, , 35F
謝謝版主大大 ^^~* 好強...
06/24 13:58, 35F

06/24 14:43, , 36F
@azure 那就會肥一點 xD http://ideone.com/Lh92EU
06/24 14:43, 36F

06/24 14:49, , 37F
我想也許可以直接放在 std::vector<boost::any> XD
06/24 14:49, 37F

06/24 14:50, , 38F
現在 union 不是也可以放 non-POD 嗎? 只是不好用...
06/24 14:50, 38F

06/24 14:50, , 39F
lol 差點忘了
06/24 14:50, 39F

06/24 15:41, , 40F
不過我需要的是「不同型別,不同實體,同時存在」
06/24 15:41, 40F

06/24 15:42, , 41F
所以無法使用 union XD
06/24 15:42, 41F
文章代碼(AID): #1Jg8jB_G (C_and_CPP)
文章代碼(AID): #1Jg8jB_G (C_and_CPP)