c++ - 用于返回带有布尔结果标志的值的标准模板
问题描述
当我开始利用 C++17 结构化绑定和 if 运算符 init 语句来获得更优雅的函数结果报告和检查时,我开始按照 C++ 核心指南 F21 执行以下操作:
std::pair<bool, int>Foo()
{
return {true, 42}; //true means that function complete with no error and that 42 is a good value
}
void main(void)
{
if (auto [Result, Value] = Foo(); Result)
{
//Do something with the return value here
}
}
然后,当然,我认为为这种返回类型提供一个可重用的模板会很好,这样就没有人必须复制该对的 bool 部分:
template <typename T> using validated = std::pair<bool,T>;
validated<int> Foo()
{
return {true, 42};
}
void main(void)
{
if (auto [Result, Value] = Foo(); Result)
{
//Do something with the return value here
}
}
这对我很有用,但现在我想知道是否有某种标准等效于这个模板,这样我就不必重新发明轮子并自己定义它。似乎任意类型值加上有效性标志将是一个有用的构造,但我在标准库中找不到任何东西。我错过了什么吗?
解决方案
std::optional正是您要问的。它甚至在描述中:
optional 的一个常见用例是可能失败的函数的返回值。与其他方法相反,如
std::pair<T,bool>
, optional 可以很好地处理构建成本高的对象并且更具可读性,因为意图是明确表达的。
示例中的if
示例看起来更简单:
#include <optional>
#include <iostream>
std::optional<int> Foo(bool fail)
{
if (!fail) return {42};
return {};
}
void process(bool fail) {
if (auto val = Foo(fail)) {
std::cout << val.value() << '\n';
} else {
std::cout << "No value!\n";
}
}
int main() {
std::optional<int> oi;
process(true);
process(false);
}
如果您真的希望Value
显式使用,那么您可以随时通过成功分支上的引用解压缩它,即auto Value = val.value()
;
您需要注意一些警告。2 从我的头顶开始:
- 性能:为什么 std::optional<int> 的构造比 std::pair<int, bool> 更昂贵?尽管对于给定的示例,带有 -O3 的最新 clang 看起来非常有说服力
注意:为简洁起见
static
添加process
- 以防止生成用于外部链接的版本。 false
如果对象是默认构造的,它将返回。这可能会让一些人感到惊讶,默认构造optional
并不默认构造底层价值。
编辑:在评论之后,我决定明确声明没有任何类型别名pair<T,bool>
或与标准库兼容的类似内容。证明某些东西不存在并不容易,但是如果有这样的类型,标准库肯定会在声明中使用它insert
,它不存在;因此,我强烈暗示它周围没有任何语义包装。
推荐阅读
- r - 我已经使用余弦相似度进行了部分匹配,但无法正确计算
- python - 导入 Tensorflow 时如何修复 ImportError
- ios - 在 iOS IKEv2 VPN 配置中使用自定义端口?
- email - 如何使用 Bamboo with Phoenix 修复“render/2 is undefined”错误
- python - Python 中的 Xor 实现给出了不正确的预测
- sql - 为什么这两个查询返回不同的结果?
- java - 如何按升序设置数字(例如:0、1、2、4、6 到 0、1、2、3、4)
- c# - 在分辨率较低的远程桌面上运行时,Selenium ChromeDriver 出现问题
- powershell - Powershell Test-NetConnection“[域]的名称解析失败”错误
- java - 找不到 libarcore