→ simon860730: integer...?03/04 09:04
→ CoNsTaR: 我的意思是 std::is_integral<T>::value 是 true 的那些03/04 11:35
→ CoNsTaR: types03/04 11:35
→ Lipraxde: 始終不明白 dependent types 的好處03/04 12:31
如果要說能讓 C++ 使用者比較有感的例子的話
dependent types 可以幫你省下一堆 switch case 或 if else
例如:
switch(v)
{
case A: f<A>()...
case B: f<B>()...
...
case Z: f<Z>()...
}
有了 dp types 就可以變成一行:
f<v>()...
→ sarafciel: C++要弄non-constexpr dependent type應該很難XD03/04 13:53
→ sarafciel: constexpr dependent types的話 我覺得現在已經是了03/04 13:55
→ sarafciel: 只是寫起來很費工而已03/04 13:55
如果把所有 cardinality 小於某個大小的 types 的所有可能都先在 compile-time 算好
,這樣會有什麼問題嗎?
或是如果用 [[exhaustive]] 之類的 attributes 來幫指定的 type 或 function 打開 d
p types 支援,沒標的就維持跟以前一樣呢?
現在 function parameters 還是不能傳進 templates 裡面,我覺得不行 QQ
→ Lipraxde: Compile 時都先算好,打算付出多少成本獲得多少收穫?03/05 11:10
→ Lipraxde: 不同 type codegen 出來的東西是不一樣的耶,雖然有印03/05 11:13
如果預設 cardinality 256 以下才自動開 dp types(這個數字應該可以用編譯器參數調
整),然後可以用 attribute 說不論某個 type 多大(只要非無限大),我想要他無視
那個 cardinality 上限支援 dp types 這樣呢?
→ Lipraxde: 象看過用 JIT 來做 (用於加速數學計算),但忘記關鍵字03/05 11:13
→ Lipraxde: 了QQ03/05 11:13
嗯,JIT 建表加速聽起來很合理 XD
推 LPH66: 就算寫 f<v>(), 實際照 v 的值去選要呼叫的 f<A> 還是得在03/05 11:32
→ LPH66: runtime 做吧 (在 v 非 constexpr 的前提下)03/05 11:33
→ LPH66: 那這其實跟寫個大 switch 好像沒什麼差別03/05 11:34
先不提如果 v 是 std::size_t 而且所有 v 的可能性你都需要自己 map 的這種極端情況
,有趣的是如果可以寫 x = f<v>() 的話,其實根本就可以不用擔心 v 實際上有哪些可
能性,例如你就可以寫:
// concrete V<...> specializations can be ad-hoc defined by user
template <std::size_t Z> struct V;
// and this would still be valid
[] (X x) { return f<V<g(x)>()>(); }
這樣你事先不需要知道 user 實際上會 specialize 哪些 V,只要 g 的邏輯讓每個 g(x)
都能確實對上一個 specialization,編譯就會過(雖然這樣好像比較像 refinement ty
pes,less like 一般的 dependent types,但意思應該有傳達到,而且這種做法也滿符
合 C++ templates 有用到才檢查的傳統的?只是現在變成"runtime 有可能用到"才檢查
而已 XD)
→ LPH66: 如果硬要把它藏起來, 我能想到接近的是 std::visit03/05 11:35
→ LPH66: (C++17 新加的內建 Visitor Pattern)03/05 11:35
我覺得這好像只是把 switch case 換一種方式寫而已?f 和 v 的關係實際上還是 detac
hed 的,i.e. 每當 v 又多了一種可能性就又要回來這邊補上
Edit: 改了一下標題,這個題目討論起來應該會更有趣 XD
推 LPH66: 對, 所以我說這是硬要藏起來而已 03/05 23:31
→ LPH66: 這樣看起來其實你的 v 用個 enum 表示好像比較像你在想的?03/05 23:35
以上面那個例子來說的話,主要想表達的是當一般程式想和 constexpr 的程式接起來的
時候非得有個手動生出來的 if else/switch case/std::visit/lookup table etc...
但如果能把像對 templates 那樣 "用到才檢查" 的規則擴展到對傳進 templates 的一般
變數 "runtime 有可能用到才在 compile-time 先算好" 的話,就好象實現了部分 depen
dent types/refinement types 的功能了,實際感受到的改變就好象是 compiler 幫你自
動建了一個 switch case/lookup table 一樣,而且不需要自己手動維護
→ LPH66: 可能狀況數很少, 所以可以先產生起來放03/05 23:35
→ LPH66: 現在對於這種 use case 好像也就是手動生出來放之後03/05 23:37
→ LPH66: 收到一個對照表裡參照, 要用時照 v 值去對照表裡找出來用03/05 23:38
話說之前看過有人實測 switch case v.s. 查表的效能比較
結果查表贏了 switch case/if else 滿多的,這個結果可以代表什麼嗎?
→ Lipraxde: 恩...最終還是會需要在 runtime 時 dispatch 吧?如果03/06 00:12
如果是單一個 function 的時候看起來好像沒什麼差
但如果 f(g(x)) 的話,runtime 就可以不需要查表兩次
因為 compile-time 就把所有 g 的輸入 f 會有什麼輸出都算好了
→ Lipraxde: 說都要 compile time 做好的話... template metaprogra03/06 00:12
→ Lipraxde: mming 還不夠好玩嗎 Orz03/06 00:13
呃,主要就是因為想要讓一般函數、變數能夠和現成的 TMP 無縫接軌,否則目前的 TMP
說實話真的有點雞肋...
什麼 first class types 啦之類的都好說,至少先讓一般變數也能傳進 templates 裡吧
QQ
※ 編輯: CoNsTaR (174.112.13.222 加拿大), 03/06/2022 13:08:20
→ adks3489: 像P1045R1這個提案嗎? 03/06 21:22