【发布时间】:2016-07-02 04:40:27
【问题描述】:
显然,如果使用 C++17 或 boost,std::optional 是从函数返回可选值的最佳选择(另请参阅 GOTW #90)
std::optional<double> possiblyFailingCalculation()
但是,如果一个人被旧版本卡住(并且不能使用 boost),那么最好的选择是什么?为什么?
我看到了几个选项:
-
STL 智能指针(仅限 C++11)
std::unique_ptr<double> possiblyFailingCalculation();- (+) 与可选的用法几乎相同
- (-) 对非多态类型或内置类型的智能指针感到困惑
-
与布尔配对
std::pair<double,bool> possiblyFailingCalculation(); -
旧式
bool possiblyFailingCalculation(double& output);- (-) 与新的 C++11
auto value = calculation()样式不兼容
- (-) 与新的 C++11
DIY 模板:具有相同功能的基本模板很容易编写代码,但是在实现健壮的
std::optional<T>类似模板时是否存在任何缺陷?-
抛出异常
- (-) 有时“无法计算”是一个有效的返回值。
【问题讨论】:
-
还有另一个选项 - 抛出异常,因为你的函数失败了。
-
我添加了该选项,但有时人们想要无异常的函数,并且“无法计算”只是一个常规的返回值。例如。你不想要函数 Edge getLargestEdge();在 Triangle 类中,在等边三角形的情况下抛出异常。
-
@DavidHaim:将其发布为答案;除非失败是一种非常常见的情况,否则人们会希望任何开销异常处理都会相当无意义,避免调用者不检查失败并得到不正确结果的风险是一个值得称赞的目标。
-
@ShadowRanger:如果意见问题是本网站的主题,并且 David 回答“抛出异常”作为返回
std::optional的最佳选择,我肯定会否决,因为它完全改变了语义。 -
@mr_T 一个更好的例子可能是
std::map查找如何在概念上返回optional<pair<const K, V>>,在查找失败时返回none而不是end()- 这是一个合理的非异常结果.
标签: c++ c++11 return-value optional