如何std::optional
适合我的代码?
我的代码包含许多看起来大致如下的函数:
bool GetName(_Out_ string& strRes)
{
// try to get/calculate the value
// value may also be empty
// return true on success, false otherwise.
}
现在我已经找到了std::optional,我只需编写代码:
std::optional<std::string> GetName()
为什么或何时不使用std::optional
?
- 我知道使用
std::optional
会带来性能价格,为了争论,让我们假设我愿意支付它。 - 我也明白这样的编码:
std::optional<int> iVal = 9;
是没有意义的。
我是不是太着迷了std::optional
?
我发现std::optional
这很自然,以至于我得出一个结论,默认情况下,我的许多本机类型 , bool
,int
应该string
被声明为std::optional
.
因此,而不是遵循以下前提:
std::optional
仅在绝对需要时使用
我倾向于:
std::optional
始终使用,除非您确定现在或将来不需要它。
问题 1
以下规则是否有效:
在以下情况下使用std::optional
:
- 在运行时计算一个值
- 计算可能失败
- 你想知道计算是否失败
问题2
如果使用std::optional
变得丰富,我会冒代码可读性问题的风险吗?
更新
答案和评论使讨论偏离了我最初关心的问题,即试图定义何时使用的经验法则std::optional
。
我将解决我得到的一些常见反馈:
您正在编写 C 风格的错误检查函数。
计算失败时使用异常。
提供一个不太好的例子来说明我的动机可能是我的错。GetName()
只是我的常见用例的一个味道。我不想关注错误是如何反映的(如果有的话),我想关注的是名字是可选的好候选人吗?
我没有说如果GetName
返回 false 意味着我的流程中有某种错误。当GetName
返回 false 时,我可以生成一个随机名称或忽略当前迭代。无论调用者如何对返回值做出反应,name
在optional
某种意义上它都是may not be present
.
我可以提供一个更好的例子:
void GetValuesFromDB(vector<string> vecKeys, map<string,string> mapKeyValue);
在这个函数中,我“被迫”提供两个容器,因为我想区分:
- 密钥在数据库中找到,它是空的。这把钥匙在
mapKeyValue
- 在数据库中找不到密钥。. 这个钥匙不会在
mapKeyValue
但optional
我可以去:
void GetValuesFromDB(map<string,std::optional<string> > mapKeyValue);
我相信我们optional
太从字面上理解这个词了。
如果您想很好地表示可空类型,我真的支持可以使用的概念。std::optional
而不是使用唯一值(如 -1、nullptr、NO_VALUE 等)
c++ 标准委员会很容易决定将 , 命名为std::optional
, std::nullable
。