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

作者: yoco315 (眠月)   2014-06-24 04:17:13
開發平台(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 可以吧
}
};
百思不得其解,盼前輩解惑。
小妹先謝過了。
作者: LPH66 (-6.2598534e+18f)   2014-06-24 04:23:00
似乎可以參考 std::get<type>(std::tuple) 的實作?唔, 仔細看才發現這要 C++14 之後才是標準 @@
作者: yoco315 (眠月)   2014-06-24 04:32:00
get(tuple) 我會作,但這邊有點不一樣。get(tuple)的時候很明確知道tuple裡面的每一個型別,透過meta-programming可以遞迴的索引到正確的member,但我現在這個狀況是get沒有辦法知道到底有多少type嘗試具現這個函數,手上有的就只有自己一個 T 這個 type @@剛試了一下 C++14 的 variable template,發現只能全域data member 不能是 template XD
作者: worldlet (純淨心靈永恆陽光)   2014-06-24 08:39:00
不能用 union 嗎 XD
作者: descent (「雄辯是銀,沉默是金」)   2014-06-24 09:45:00
連語法都看不懂
作者: azureblaze (AzureBlaze)   2014-06-24 09:55:00
寫工具掃所有用到a.get<T>()的地方建tuple(超大工程要同時123應該一定得跑兩個phase?
作者: yoco315 (眠月)   2014-06-24 10:18:00
azureblaze,有想過,但可惜a.get<T>會在template裡面被呼叫而且是template裡面的template裡面的template裡面的..除非我的工具很完整的支援 c++ template 型別推導,不然 qq
作者: azureblaze (AzureBlaze)   2014-06-24 10:22:00
我覺得就是因為太複雜所以variable template不能這樣用
作者: loveme00835 (髮箍)   2014-06-24 10:24:00
virtual function call 的 cost 可接受?
作者: yoco315 (眠月)   2014-06-24 10:24:00
我快要放棄了了 XD 最後可能會對 3 妥協
作者: azureblaze (AzureBlaze)   2014-06-24 10:24:00
如果又把他extern或指標傳出去那還會更複雜試了一下variant的寫法效率好像會更糟http://ideone.com/MMPhYa 至少不用lock static?
作者: yoco315 (眠月)   2014-06-24 11:12:00
哇!好聰明的手法 XD 竟然用 static variable addr 當 key學起來,ㄎㄎ
作者: carylorrk (carylorrk)   2014-06-24 12:36:00
所以一定要 runtime 來查嗎~?
作者: kwpn (ITSST)   2014-06-24 12:39:00
boost variant就是這個效果吧
作者: loveme00835 (髮箍)   2014-06-24 12:40:00
我的解法 ideone.com/yzomRg
作者: carylorrk (carylorrk)   2014-06-24 12:53:00
variant 不是類似 union 嗎?我有搞錯嗎XD?版大神解~compile time 就定位的到了
作者: azureblaze (AzureBlaze)   2014-06-24 12:56:00
union只吃POD不過上面的作法非POD都會leak 還是得包層virtual
作者: carylorrk (carylorrk)   2014-06-24 13:05:00
我的意思是 variant 像 union 無法依 type 存不同值吧?不是很懂非 POD 會 leak 的意思@@ 可以請教一下嗎XD?沒事 我知道了~
作者: yoco315 (眠月)   2014-06-24 13:58:00
謝謝版主大大 ^^~* 好強...
作者: loveme00835 (髮箍)   2014-06-24 14:43:00
@azure 那就會肥一點 xD http://ideone.com/Lh92EU
作者: yoco315 (眠月)   2014-06-24 14:49:00
我想也許可以直接放在 std::vector<boost::any> XD
作者: suhorng ( )   2014-06-24 14:50:00
現在 union 不是也可以放 non-POD 嗎? 只是不好用...
作者: loveme00835 (髮箍)   2014-06-24 14:50:00
lol 差點忘了
作者: yoco315 (眠月)   2014-06-24 15:41:00
不過我需要的是「不同型別,不同實體,同時存在」所以無法使用 union XD

Links booklink

Contact Us: admin [ a t ] ucptt.com