据我所了解,您可以有两种方式实现一个函数,有时不返回结果(例如在人员列表中找不到某个人)。
*- 我们忽略裸指针版本,可以使用带有布尔标志的pair或抛出异常的版本。
boost::optional<Person> findPersonInList();
或者std::unique_ptr<Person> findPersonInList();
那么有没有理由更喜欢其中一个而不是另一个呢?
据我所了解,您可以有两种方式实现一个函数,有时不返回结果(例如在人员列表中找不到某个人)。
*- 我们忽略裸指针版本,可以使用带有布尔标志的pair或抛出异常的版本。
boost::optional<Person> findPersonInList();
或者std::unique_ptr<Person> findPersonInList();
那么有没有理由更喜欢其中一个而不是另一个呢?
NotFound
而不是NullPointer
吗?它们有什么区别? - Matthieu M.NotFound
很明显更受青睐,因为它更直接地表达了语义。然而,在这个上下文中抛出异常也不是一个好的选择。 - Konrad Rudolphif
比嵌套 try/catch
更简洁),如果他们不期望它(这次没有意义),他们仍然受到保护。 - Matthieu M.通常情况下,您的意图应该使用boost::optional
表达而不是std::unique_ptr
。尽管如此,特殊情况下的find
操作可能应该遵循标准库的方式来实现,假定您底层类型具有迭代器的概念:如果找不到元素,则返回指向end()
的迭代器;否则返回指向该元素的迭代器。
boost::optional
更清晰地表明了您的意图。您需要明确记录空的 std::unique_ptr
表示没有值可返回。
boost :: optional
的目的就是表达这个特定意图。因此,基本上,它更清晰,按定义而言。在这里没有什么好反对的,这是一个事实性的论点。此外,您忽略了unique_ptr
的内在语义:它表示(独占)所有权。 - Konrad Rudolphboost::optional
能更清晰地表达意图,但如果您查看我的答案,您将会发现它存在一些潜在问题。它的本意是存储一个值,而不是动态分配的类,因此不适用于拥有多态类实例的情况。那时,您应该使用std::unique_ptr
,在其上包装boost::optional
来表达它可能为空是没有意义的。 - Matthieu M.unique_ptr
。C++ 标准中并没有规定 unique_ptr
不能是空的。而且,对我来说,一个空的 unique_ptr
完美地表达了“未找到”的含义,就像 optional
一样。在我看来,optional
的真正优势在于,你不必像 Matthieu 所说的那样支付动态内存分配的成本。 - Chris Drewoptional
表示函数可能不会给你返回结果(这不是错误情况)。unique_ptr
告诉你一些关于所有权语义的信息(并且更适合与null一起使用,以表示错误)。optional
来表达这一点,以明确函数可能不返回任何内容(而不返回任何内容不是错误情况)。unique_ptr
,或者更好的方法是抛出异常。
unique_ptr
对于查找操作非常不合适,你需要的正是一个原始指针,而布尔标志是完全不必要的! - Andrei Titaboost::optional
。 - Konrad Rudolph