作者CoNsTaR ((const *))
看板C_and_CPP
标题[闲聊] C++ 支援相依型别的话会长怎样?
时间Thu Mar 3 18:04:01 2022
如题,C++ 有可能在未来支援 dependent types 吗?如果支援的话大家觉得会长怎样?
一些 cardinality 无限大的 types 不支援完全可以理解
但是像 integrals, std::array of integral 之类的 types 要支援应该不是问题?
到了 C++20,已经很多东西都有 constexpr 的版本了
用起来已经比之前的版本开心很多,但仍然和真正的 dependent types 有一段不小的差
距
如果有一天真的能把变数当作 template arguments 传进 templates 里,C++ 真的会有
用很多
或者退而求其次,至少支援个 constexpr function parameters 也好
这样至少在 constexpr 的前提下有 dependent types 可以用
有 C++ 有没有可能在未来支援 dependent types 的挂吗?
或是有没有看过相关的提案或是正式的讨论呢?
--
※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 174.112.13.222 (加拿大)
※ 文章网址: https://webptt.com/cn.aspx?n=bbs/C_and_CPP/M.1646301843.A.E7A.html
1F:→ simon860730: integer...?03/04 09:04
2F:→ CoNsTaR: 我的意思是 std::is_integral<T>::value 是 true 的那些03/04 11:35
3F:→ CoNsTaR: types03/04 11:35
4F:→ 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>()...
5F:→ sarafciel: C++要弄non-constexpr dependent type应该很难XD03/04 13:53
6F:→ sarafciel: constexpr dependent types的话 我觉得现在已经是了03/04 13:55
7F:→ sarafciel: 只是写起来很费工而已03/04 13:55
如果把所有 cardinality 小於某个大小的 types 的所有可能都先在 compile-time 算好
,这样会有什麽问题吗?
或是如果用 [[exhaustive]] 之类的 attributes 来帮指定的 type 或 function 打开 d
p types 支援,没标的就维持跟以前一样呢?
现在 function parameters 还是不能传进 templates 里面,我觉得不行 QQ
8F:→ Lipraxde: Compile 时都先算好,打算付出多少成本获得多少收获?03/05 11:10
9F:→ Lipraxde: 不同 type codegen 出来的东西是不一样的耶,虽然有印03/05 11:13
如果预设 cardinality 256 以下才自动开 dp types(这个数字应该可以用编译器参数调
整),然後可以用 attribute 说不论某个 type 多大(只要非无限大),我想要他无视
那个 cardinality 上限支援 dp types 这样呢?
10F:→ Lipraxde: 象看过用 JIT 来做 (用於加速数学计算),但忘记关键字03/05 11:13
11F:→ Lipraxde: 了QQ03/05 11:13
嗯,JIT 建表加速听起来很合理 XD
12F:推 LPH66: 就算写 f<v>(), 实际照 v 的值去选要呼叫的 f<A> 还是得在03/05 11:32
13F:→ LPH66: runtime 做吧 (在 v 非 constexpr 的前提下)03/05 11:33
14F:→ 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)
15F:→ LPH66: 如果硬要把它藏起来, 我能想到接近的是 std::visit03/05 11:35
16F:→ LPH66: (C++17 新加的内建 Visitor Pattern)03/05 11:35
我觉得这好像只是把 switch case 换一种方式写而已?f 和 v 的关系实际上还是 detac
hed 的,i.e. 每当 v 又多了一种可能性就又要回来这边补上
Edit: 改了一下标题,这个题目讨论起来应该会更有趣 XD
17F:推 LPH66: 对, 所以我说这是硬要藏起来而已 03/05 23:31
18F:→ 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 一样,而且不需要自己手动维护
19F:→ LPH66: 可能状况数很少, 所以可以先产生起来放03/05 23:35
20F:→ LPH66: 现在对於这种 use case 好像也就是手动生出来放之後03/05 23:37
21F:→ LPH66: 收到一个对照表里参照, 要用时照 v 值去对照表里找出来用03/05 23:38
话说之前看过有人实测 switch case v.s. 查表的效能比较
结果查表赢了 switch case/if else 满多的,这个结果可以代表什麽吗?
22F:→ Lipraxde: 恩...最终还是会需要在 runtime 时 dispatch 吧?如果03/06 00:12
如果是单一个 function 的时候看起来好像没什麽差
但如果 f(g(x)) 的话,runtime 就可以不需要查表两次
因为 compile-time 就把所有 g 的输入 f 会有什麽输出都算好了
23F:→ Lipraxde: 说都要 compile time 做好的话... template metaprogra03/06 00:12
24F:→ Lipraxde: mming 还不够好玩吗 Orz03/06 00:13
呃,主要就是因为想要让一般函数、变数能够和现成的 TMP 无缝接轨,否则目前的 TMP
说实话真的有点鸡肋...
什麽 first class types 啦之类的都好说,至少先让一般变数也能传进 templates 里吧
QQ
※ 编辑: CoNsTaR (174.112.13.222 加拿大), 03/06/2022 13:08:20
25F:→ adks3489: 像P1045R1这个提案吗? 03/06 21:22