ColorfulBoar 最近的时间轴更新
ColorfulBoar

ColorfulBoar

V2EX 第 551680 号会员,加入于 2021-07-24 11:55:03 +08:00
今日活跃度排名 676
ColorfulBoar 最近回复了
1 天前
回复了 ligiggy 创建的主题 C++ 请教大家一个函数的定义问题
你这个问法可能不太对……首先不怎么建议问(不管别人还是自己)选 A 还是选 B 这种问题,因为答案很可能是 C ( std::optional 或者 std::expected ),也可能预设的选项会干扰别人的思路,而且很可能会得到一堆没怎么说清楚理由的个人偏好。

一个可能的一般性思路是如果不是很确定怎么解决一个问题的话,那我们可以尝试找个能同时解决多个问题的方案(一方面能交叉对比排除掉一些错误答案,一方面一个模式如果是有效的话很难相信只在一个地方起作用)。比如它最好能同时锻炼某种学习 C++时需要的独立整蛊能力和提供能迁移到其他语言中的知识。所以或许可以尝试一下下面这套办法:
1. 先找找最新的与 error handling 相关的 proposal ,然后发现最近的进展差不多在 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p0323r10.html 里面( std::expected ),花几分钟读完 motivation ,就脱离了很多人长时间里陷入的那种凭感觉选一种方式但也说不清为什么的阶段了。继续读需要先看看里面提到的 std::optional 那篇(以及后续的改进 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p0798r8.html 与 std::expected 那篇里面提到的类似 proposal ),如果感觉读着很爽就直接顺着往下看。
2. 由于 C++23 还不知道什么时候能用上,使用 std::expected 的例子可能不太多,纯读 proposal 如果感觉无聊 /读不下去的话可以拿对 std::optional 的讨论与使用凑合一下(比如 https://devblogs.microsoft.com/cppblog/stdoptional-how-when-and-why/,或者 CppCon 里面应该有一些相关的 talk ,由于一个话题很可能会讲好几次所以挑个喜欢的跳着看吧)然后假装 std::optional<T>就是 std::expected<T, nullopt_t>来辅助理解 std::expected 。另一个选择是看一下 Rust 里面和 std::expected<T,E>类似的处理方式 Result<T,E>是怎么设计和使用的( https://doc.rust-lang.org/book/ch09-02-recoverable-errors-with-result.htmlhttps://doc.rust-lang.org/rust-by-example/error.html
3. 以上文档可能还有一些没直接说清楚的问题(比如 pair<bool, T>和 optional<T>不考虑后者在不必要时能不初始化 T 等问题之后好像有点像,或者除了感觉不爽以外还能用什么借口拒绝 tuple ,或者为啥那 proposal 要用 monadic 这么神经病的词,或者什么别的在你心里像是长了条猪尾巴一样乱晃的问题),这个时候看一些抽象一点却又没那么抽象的东西,比如 type system 相关的材料,会比较舒服。关键字大概是 algebraic data type, product/sum type 和 monad 。一个比较具体但不够深入的选择是 Programming with Types: Examples in TypeScript 的第 3 章和第 11 章,当然如果不喜欢 Typescript 或者嫌它没讲清楚(的确如此)也有大把的其他饲料可以选择就是了。
2 天前
回复了 soberzml 创建的主题 Minecraft 怎么开始沉浸 minecraft
@soberzml 比如 Unity ?

我感觉打 mod 打到头也就是个某种其他品类游戏的劣化版,毕竟 minecraft 那个代码质量在那摆着,有开发 mod 的精力早就能造个更好的游戏出来了,不管是写逻辑还是写 shader 能在正常环境下写肯定比在它那坨代码基础上整蛊来得舒服( https://www.zhihu.com/question/24459078 我不熟悉 Java ,不过看别人研究结果感觉真的吓人,这种 mod 谁爱写谁写去我是绝不会碰的,跟别人说什么「大不了自己写 mod 」就跟说「大不了自己反汇编」一样离谱)
如果是为了玩的话,想好好做 gameplay 的人也会做自己的游戏而不是在 mc 基础上忍受那么大的限制修改,做优化的空间也要大得多。比如如果你想像上面几楼说的那样尝试流水线量产点东西,那远不如直接玩戴森球什么的快乐,其他游戏类型同理;反过来自己做的话有学会在 mc 里面搞稍微复杂一点东西的时间已经够在 unity 里面摸出来个效果好得多的 demo 了,哪怕非要坚持游戏引擎不算 metagame 那也可以尝试一下 roblox 一类的东西( mc 发展上限就那样了,这个还有点想像空间)
如果是为了看的话,想建东西玩在正经的开发环境下(比如 blender )效率也远大于打了一堆补丁的 mc (更别说原版了……好看点的东西都不是真的一块一块垒出来的),视觉效果更是完全没法比,毕竟离线渲染质量远超实时渲染,而且优化水平也完全不一样,不管你在 mc 里面搞出来什么东西都能在其他地方用小得多的 overhead 更快地实现更好的效果。用 mc 搭大型建筑就有种拿手指在触摸屏上画画的感觉,总有人能搞出不错的效果来,但指绘还是条歪路,我还是会推荐好好练数位板不要整这些乱七八糟的,因为它们在炫技以外其实并没有贡献什么多样性,还会误导一些本来可能做出更好东西的人。

在游戏之外(这些问题不只是 mc 有,但夸 mc 的实在是太好找了,所以我干脆就写一些纯反面的想法),很多被拿出来吹的展示视频都跟真的自己玩效果大不一样(制作者的熟悉程度远超普通玩家,背后其实有很多坑;视频会经过后期处理,主要目标是为了让你看得爽,会选择特定的视角,进行一定的剪辑与加速,并且录制过程会掩盖帧数不足等游戏运行中产生的问题,进一步加大了和真正玩的时候的差距),整个游戏社区声音最大的是玩了非常非常久的,久到占据了它们接触新东西的时间与精力,剩下的人很多像是复读机一样扩散这些观点把前面那类人辛苦做出来的东西当成是正常游戏体验,哪怕它们本身从来没亲自见过。它能打开更大的世界吗?我觉得大体上不但没有,反而还形成了一些阻碍,想像一个没咋接触过的人,在能接触到的流量里面最可能看到的是 mc ,然后搜一搜发现都是精心制作的视频,问一问基本上也都跟这个问题里面一样得到一些啥都能干感觉有问题是你自己不行的回复,然后真的进去感觉跟想像中的不太一样,再出来问问得到的答案是打 mod ,然后回去打了一堆 mod 折腾了很久很久之后,假如没放弃的话,积累了难以迁移的技能并慢慢融入了某个社区里开始作为新的传播源宣传起 mc 来(当然不走到这一步也可以云一下然后开始宣传),觉得还是在 mc 里面做东西舒服,那些「专业」软件太难了;如果半路放弃了,反而可能不怎么愿意多说什么,毕竟这种很容易被当成是自己能力不行 /审美有异……在这个过程中,本可能有的通过接触并认真思考更多类型的游戏改善审美或者通往成为创作者的道路反而是变得更难找与更难走了,然后往路上扔石头的人还会一边埋路,一边觉得自己完全是无辜的,一边高喊自由与创造与爱。

总之,想看好听的话实在是太容易了,毕竟销量这么高(虽然这和质量没有相关性,不然宝可梦那么好卖想必游戏质量一定很好吧),现有的信息传播模式也对它更有利,但反过来想找个喷个爽的就不太容易了,它们的传播性也远远不如前者,所以我还是来提供一些可能不太容易在其他地方见到的负面意见好了。毕竟,正如每次消费都是在投票一样,每次制造并传播某种信息也是在投票,我还是想在这上面更积极一些,不谈做出什么改变,至少作为某种练习为日后做一些准备也好。
3 天前
回复了 soberzml 创建的主题 Minecraft 怎么开始沉浸 minecraft
我强烈建议换个思路:Minecraft 比起游戏来更像是个超低配游戏引擎,那玩它感觉无聊的话不如直接去玩一个喜欢的游戏引擎!
一个猜想,估计没错:好像 Unix 和 C 的狂热粉丝比例也不小,而且味道有点像,所以有没有可能真正的坏东西是 Ken Thompson ?
7 天前
回复了 zbzzh 创建的主题 分享发现 发现神器,无须代理直连 github 和 v2ex
虽然上一个作者本人的贴子里有只洛林的棕色栗子兔说在这发等于火车上卖票,但其实它不仅能在中国用,在其他国家即使没有墙也能加速 GitHub 。谢谢你作者拯救了我的网络!
14 天前
回复了 ligiggy 创建的主题 C++ 左值右值,有没有通俗易懂且具体的资料
Effective Modern C++是写于 C++14 版本的,现在已经发生了一些变化(在使用上变化不是很大,概念上变化比较大)。cppreference 定义照抄标准而且后面全是枚举例子,好像只看它很难看懂发生了什么。CppCon 里的好像很多是教你怎么用的,没咋看过,或许用多了也能发展出一些直觉吧。

为了理解它,如果不想在那 1800 多页的标准构成的粪坑里游泳的话,现成的材料里 C++ Templates: The Complete Guide 第二版关于 value categories 的附录可能好一点,就几页纸,概念又比较正确(不过 reference collapsing 放在正文中间的好像作者还建议第一次读跳过去的部份)。


简单来说大概是这么理解的(这只是我的理解方式,估计肯定有某些不符合标准的地方,另外可能先跳到 4 会好一点):

1. value categories 是表达式的属性而不是变量的属性或者别的什么玩意的属性。比如 int a = -1;这里的 a 并不是一个表达式,它不是啥左值,写在等号左边就是左值这个想法是错的。而 C++11 里为了 move semantics 等需求引入的 lvalue/rvalue reference 是两种不同的类型,它们是和表达式正交的属性,比如 void push_back(string&& x);里面的 x 的类型是右值引用 string&&,但函数定义里面如果直接写一个表达式 x 的话则是一个 glvalue 的表达式。

2. 自 C++17 起表达式分为两类:glvalue 和 prvalue ,前者提供某个位置信息,后者提供初始化或者修改的时候所需的值。从这个版本起只需要以上二者就可以理解我们需要的东西,不再需要另外定义 lvalue 和 rvalue 了。乍看之下存在一些显然有问题的地方,比如 int a = b;里面的 b 既提供了 b 这个变量的位置又提供了初始化 a 所需要的值。实际上 C++里存在以下两种 value categories 之间的直接转换(具体行为受到类型影响,但大致上符合直觉):
------2.1 lvalue-to-rvalue ,名字叫这个,但它实际上是把一个 glvalue 转换成一个 prvalue (正如前面所说,我们已经不需要 lvalue 和 rvalue 这两种 value categories 了),这个 prvalue 在用来提供值的时候会从转换成它的 glvalue 提供的位置信息里面来获取相应的值(不同的类型的具体行为不太一样,但大致上是符合直觉的)。比如之前提到的 int a = b;里面的 b 就是先转换成了 prvalue 才能提供用来初始化 a 的值的。
------2.2 temporary materialization conversion 机制允许通过一个 prvalue 生成一个临时对象然后把它的位置作为一个 glvalue 放在好像需要 glvalue 的地方,用这种机制可以在需要 const lvalue reference 的地方传进去一个 prvalue 。但这种机制发挥的场合是受限的,直觉上只有找不到 glvalue 让这个 prvalue 起到初始化的作用的时候才会发生这种转换。比如 string a = string(string(string()));里内层表达式是 prvalue ,它会一直往外抛,直到找到 glvalue a 后进行一次初始化,C++17 里利用这个特性实现了所谓的 guaranteed copy elision 。这种特性生成的 glvalue 表达式不能用在=的左边,也不能用来初始化 non-const lvalue reference ,由此我们在 glvalue 中分出一个新的子类 xvalue ,它只通过屈指可数的几种情况生成,感觉上更像是一种技术手段。

3. 作为 type 的 lvalue 和 rvalue reference 是与表达式的 value categories 正交的性质。但二者存在下面的相互作用:
------3.1 lvalue reference 只能被 glvalue 里面不是 xvalue 的那一类所初始化(这一类叫作 lvalue ),而 rvalue reference 只能被剩下的表达式初始化(即 xvalue 与 prvalue ,这一类叫作 rvalue ),并且不接受从 glvalue 转化来的 prvalue 。如果试图扔掉 lvalue/rvalue 的话,大概可以说 l/rvalue reference 只能被本来是 glvalue/prvalue 的表达式初始化,这么说看起来更简单,但我不知道能不能严格地定义。
------3.2 函数返回值的分类,或者说由调用这个函数构成的表达式的 value category ,受到返回值类型的影响:返回值为左值引用给出 lvalue ,右值引用给出 xvalue ,非引用类型给出 prvalue 。如果试图扔掉 lvalue/rvalue 的话大概思路和 3.1 一样沿着返回路径回溯看看源头是什么(碰到引用的时候看是谁初始化的引用类型),同样我也不知道能不能严格定义这种偷鸡理解。
------3.3 存在向 rvalue reference 的强制转换 std::move ,以及利用 reference collapsing (引用的引用会变成一个单层引用,左引用会传染下去)机制做的所谓 universal reference 与 perfect forwarding
------3.4 借由这种相互作用,我们可以通过表达式本身匹配上不同的函数调用 copy/move 相关的重载实现 move semantics ,也可以通过包含函数的表达式本质上的 value category 可以一直追溯到产生那个值的地方这个特性来实现 guaranteed copy elision 。

4. 总的来说细节很多,并且散布在标准的各处,它们之间还有相互作用,我已经看吐了(虽然吐过之后好像不怕读标准了),所以在不出意外的时候我打算用这个简化的理解:表达式分两类,一类提供广义的位置(最终用来取出来一个值或者修改一个值),一类提供广义的值(最终被某个位置吃掉),二者可以但只应该在必要的时候相互转化,毕竟从位置里取出来一个值或者用某些值创建一个临时对象是有代价的,我们尽量晚地做这件事,说不好可以少干一点或者干脆不用干了。左 /右引用是类型而不是表达式分类,但它们大致上可以通过追溯源头来反应表达式是哪类的:当源头是位置的时候引用的类型是左值引用,是值的时候引用的类型是右值引用,其中左值引用具有传染性,除非被某种转换(比如 std::move )截断。我们利用这个机制来实现 Modern C++里面的诸多特性。剩下的都是技术细节。


题外话:我一直很好奇 2022 年咋还有 C 和 C++都分不清楚的……
@woshichuanqilz 像又不完全像,比不贴类纸膜的 Appen Pencil 那种跟玻璃磨擦的手感肯定是接近多了(贴了的没用过不知道),但和纸还是有区别。延迟应该不是 iPad 的问题(除非你手里真的是老古董 iPad 2 ,但那个不支持 Apple Pencil )更可能是因为你开了防抖( Procreate 里面的 streamline ),关掉或者调低一些就正常了,虽然我觉得打开一些防抖但画慢点更合理……
原装 Apple Pencil 已经够难用的了,200 的笔真的没用过,说实话我还挺期待能烂成啥样的
另外同样是 200 元另一个选择是买块体验比它们更好的数位板,你要不要考虑一下?
21 天前
回复了 ColorfulBoar 创建的主题 分享发现 求糟糕的中文 podcast(播客)排雷?
@noyidoit 是任意一个能在字面上取反的东西(把 E 和ヨ换成 A 和∀也行,我现有的输入法配置打假名比打符号方便所以就用了现在这一组),为了更夸张一点我用了字形上相反而不是字面意思上相反的东西(考虑到一个词字面意思和它真正表达的含义之间没有什么必然联系,认为字面上取反就是相反的事物这种认知能力跟试图直接翻转文字像素点来取反也没什么区别)。
21 天前
回复了 ColorfulBoar 创建的主题 分享发现 求糟糕的中文 podcast(播客)排雷?
@Deepseafish 迄今为止我没有发现有谁可以稳定高速生产足够高质量的内容,所以反过来稳定更新意味着内容质量不能满足我。
稳定高速可以定义成一周一次一小时左右,也可以用一个动态的定义:调整作为判别标准的频率直到找到第一个能以这个频率生产足够高质量的内容的人(或者相信自己大概能以这个频率生产),然后把那个间隔凭感觉打个折扣,对我来说这个动态获得的结果也是远远超过前面随意给出的版本的。
足够高的质量大概意味着某种局部极大值,而在有多个维度的时候这理论上不是那么的困难,只需要在至少一个或大或小的地方超越了(在该内容诞生以前)公共信息里现有的最好水平既可。它的反面可以是完全搬运 /复读某种观点(多数时候还要再加上一点自己的劣化),或者说成为了某种思想的奴隶也行( Keynes 意义下)。
剩下几点你可以选择你喜欢的方式来解释,如果一个东西看起来有逻辑又无法理解,除了让作者更详细地解释以外(我决定现在不去做,因为每一点都需要比起以上文字来篇幅更大的解释)还有一个或许有趣的选择:把它当成不再被作者控制的文本,改写成你觉得合理的内容。我觉得这样比较有趣是因为这么做或许能创造一些新的东西出来。

@其他的可能在对我说的回复们 我觉得你们阅读到的东西跟我想说的东西有点出入,比起具体解释细节来可能更重要的是……在加粗的那半句话及以前的东西才是我想问的,我想试试这么问是不是能避免甩个名字就走的回复,以及更重要的,我比较好奇其他人会用什么样的原因 /方式做出一个负面评价或者排除掉某些东西。一般来说我相信这和找到好的东西某种程度上是对偶的,但排除掉错误的选项要更容易一些。至于后面的内容完全是「如果我看到这个问题我会回答什么」,虽然绝不是不认真写的,但主要的目的是作为一个例子来试图在一定程度上改变回复的种类,而不是作为讨论的中心。
关于   ·   帮助文档   ·   API   ·   FAQ   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   1307 人在线   最高记录 5497   ·     Select Language
创意工作者们的社区
World is powered by solitude
VERSION: 3.9.8.5 · 14ms · UTC 18:23 · PVG 02:23 · LAX 10:23 · JFK 13:23
Developed with CodeLauncher
♥ Do have faith in what you're doing.