Lobsters | 原文链接 | 2026-09-14 收录

在 C++ 里偷懒:让 value_or 的实参不再被提前求值

来源: cpp-rendering.io — 2026-09-12

概述

文章从一个反直觉的例子出发:std::optional a = 50 之后,a.value_or(complex_computation()) 竟然先打印出 Compute 才返回 50,而 C++ 的信条本来是「不用不为它付钱」。原因是 value_or 是函数,函数实参必须在调用前求值;C++23 的 or_else 接受可调用对象可以解决这个具体场景,但 std::map::try_emplace 等函数有同样的问题,需要一个通用解。作者先看 MSVC 的 value_or 实现,确认它只在 fallback 分支把参数转成 T,因此让计算发生在那个时点即可;随后给出一个极简的 Lazy 模板:内部存放一个 initializer 可调用对象,通过隐式转换运算符在真正需要物化结果时才调用它。局限性也明说:不记忆化,同一个 Lazy 用两次会算两遍;转换运算符没有约束,连 bool 都能转,可能出意外。下一篇将做支持记忆化、只转换到初始化器返回类型的更健壮版本,并实测运行时开销。

核心要点

金句

C++ 的信条是「不用不为它付钱」,可在这个例子里第一次计算根本没必要,我们照样付了钱。
返回 Lobsters 首页