Google C++每周贴士 #163: 传递`absl::optional`参数

本文介绍了在C++中如何处理`absl::optional`参数,强调了传递可选参数的正确方式,以避免不必要的拷贝和效率问题。建议在需要可选且可能为空的参数时使用`absl::optional`,并提醒虽然可以通过间接手段实现可选引用,但不推荐这样做。文章还提到`absl::optional`在类成员和函数返回值中的应用,以及在某些情况下直接传递包裹在`absl::optional`内的对象可能是合适的。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

(原文链接:https://abseil.io/tips/163 译者:clangpp@gmail.com)

每周贴士 #163: 传递absl::optional参数

空值真的是十亿美元的错误吗?

问题

比方说你需要实现一个函数,接收一个可能存在也可能不存在的参数。你可能禁不住去用现代的,闪瞎狗眼的absl::optional。但是吧,如果这个对象大到了应该传引用的程度,那也许absl::optional并不是你真的想要的。考虑如下两个声明:

void MyFunc(const absl::optional<Foo>& foo);  // 以值拷贝
void MyFunc(absl::optional<const Foo&> foo);  // 编译错误

第一个选项做的可能跟你想象的不同。如果有人传了一个FooMyFunc,这个Foo会被以值拷贝到absl::optional<Foo>,然后以引用传进这个函数。如果你本来的目的是避免拷贝Foo,那你所托非人了。

第二个选项相当不错,但不幸的是,absl::optional不支持。

建议

如果你需要一个可能不存在的参数,以const *传递之,并以nullptr表示“不存在”。

void MyFunc(const Foo* foo);

这种方式跟传递const Foo&一样高效,但它支持空值。

std::optional的文档指出,你可以用std::reference_wrapper来曲线救国,绕过可选的引用(optional reference)不被支持的事实:

void MyFunc(absl::optional<std::reference_wrapper<const Foo>> foo);

然而,这里的零碎儿太多了,而且读起来费劲。因此,我们不建议用它。

absl::optional到底有什么用?

当你拥有一个可选的东西的时候,absl::optional就有用武之地了。例如,类成员和函数返回值通常跟absl::optional搭档得很好。如果你不拥有一个可选的东西,那如上所述,就用指针吧。

例外

如果你的对象小到不需要以引用传递,你也许可以以值传递一个包裹在absl::optional里的对象。例如:

void MyFunc(absl::optional<int> bar);

如果你期待你函数的所有的调用者都已经有一个对象包在absl::optional里了,那你也许可以收一个const absl::optional&。但是,这挺少见的;通常这只会发生在你的函数是文件/库的私有函数的时候。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值