我有一个返回自定义类结构的函数,但是如何处理我希望通知用户函数失败的情况,如返回false.
我的函数看起来像这样:
Cell CSV::Find(std::string segment) {
Cell result;
// Search code here.
return result;
}
Run Code Online (Sandbox Code Playgroud)
因此,当成功时,它会返回正确的结果,但是当它失败时我该如何处理?
我想在Cell中添加一个布尔方法来检查什么Cell.data是空的(Cell.IsEmpty()).但我是否以过于复杂的方式思考这个问题?
小智 41
有三种一般方法:
std::optional<Cell>(或其他一些可能或可能不包含实际的类型Cell).bool,并添加一个Cell &参数.其中哪一个最好取决于您打算如何使用此功能.如果主要用例传递有效段,则一定要使用例外.
如果该函数的部分设计是可以用来判断一个段是否有效,则异常是不合适的,我的首选是std::optional<Cell>.这可能不适用于您的标准库实现(这是C++ 17的功能); 如果没有,boost::optional<Cell>可能是有用的(如Richard Hodges的回答中提到的).
在评论中,而不是std::optional<Cell>用户建议expected<Cell, error>(不是标准的C++,而是针对未来的标准提出,并且在此std之前可以在命名空间之外实现).如果有多种可能的原因,这可能是一个很好的选择,可以添加一些指示,说明为什么找不到传入Cell的segment参数.
我包括的第三个选项主要是为了完整性.我不推荐它.它是其他语言中流行且通常很好的模式.
这个函数是一个查询,它可以有效地找不到单元格,或者它是一个必要条件,期望找到单元格?
如果是前者,则返回一个可选的(或可空的指针)单元格.
如果是后者,如果没有找到则抛出异常.
前任的:
boost::optional<Cell> CSV::Find(std::string segment) {
boost::optional<Cell> result;
// Search code here.
return result;
}
Run Code Online (Sandbox Code Playgroud)
后者:就像你拥有它一样.
当然还有基于c ++ 17变体的方法:
#include <variant>
#include <string>
struct CellNotFound {};
struct Cell {};
using CellFindResult = std::variant<CellNotFound, Cell>;
CellFindResult Find(std::string segment) {
CellFindResult result { CellNotFound {} };
// Search code here.
return result;
}
template<class... Ts> struct overloaded : Ts... { using Ts::operator()...; };
template<class... Ts> overloaded(Ts...) -> overloaded<Ts...>;
void cellsAndStuff()
{
std::visit(overloaded
{
[&](CellNotFound)
{
// the not-found code
},
[&](Cell c)
{
// code on cell found
}
}, Find("foo"));
}
Run Code Online (Sandbox Code Playgroud)