我有一个搜索向量的函数,如果找到了该项,则将其返回。但是我想知道最好的软件方法来处理,如果找不到的话。
我创建了一个函数,可以返回-1或类似的东西,但是与返回类型不匹配。
koalaGraph::PVertex Koala::lookUpVertexbyName(const std::string&vertexName, const std::vector<koalaGraph::PVertex>& koalaVertices) {
for (size_t i = 0; i < koalaVertices.size(); i++) {
if(koalaVertices[i]->info.name == vertexName)
return koalaVertices[i];
}
}
如果遇到要搜索的项目不在矢量中的情况,则程序将退出。
答案 0 :(得分:9)
您可以使用std::optional
#include <optional>
std::optional<koalaGraph::PVertex>
Koala::lookUpVertexbyName(const std::string&vertexName,
const std::vector<koalaGraph::PVertex>& koalaVertices) {
for (size_t i = 0; i < koalaVertices.size(); i++) {
if(koalaVertices[i]->info.name == vertexName)
return koalaVertices[i];
}
return {};
}
int main()
{
Koala k;
//...
auto maybeVertex = k.lookUpVertexByName("foo",vertices);
if(maybeVertex)
koalaGraph::PVertex&& vertex = *maybeVertex;
//alternatively
if(maybeVertex.has_value())
//found
}
答案 1 :(得分:3)
您可以使用for
循环并返回一个迭代器。
std::vector<koalaGraph::PVertex>::const_iterator
Koala::lookUpVertexbyName(
const std::string&vertexName,
const std::vector<koalaGraph::PVertex>& koalaVertices)
{
for(auto iter = koalaVertices.begin(); iter != koalaVertices.end(); ++iter) {
if(koalaVertices[i]->info.name == vertexName) {
return iter;
}
}
return koalaVertices.end();
}
进一步检查是否退回了end
。 end
指示是否找到该值。
auto iter = <fucntioncall> // lookUpVertexbyName
if (iter == <vector>.end() {
// abort or do what ever you want
}
要使用该值,必须取消引用迭代器。不要取消引用end
迭代器,它会使您进入Neverland->未定义的行为。
std::string test = *iter;
答案 2 :(得分:2)
为什么不使用std::find_if
而不是重新发明轮子。参见此link。
struct equal
{
equal(const std::string& vertexName) : vertexName_(vertexName) { }
bool operator()(const koalaGraph::PVertex& pVertex) const
{
return pVertex->info.name == vertexName_;
}
private:
std::string vertexName_;
};
然后:
std::find_if(koalaVertices.begin(), koalaVertices.end(), eq(vertexName));
关于处理函数中的错误的说明,已经有多种方法可以采用。返回迭代器而不是对象(您也将避免使用这种方式进行复制)是其中之一。 end()
迭代器将指示未找到名称。
答案 3 :(得分:1)
有三种退出函数的方法:
std::abort
或std::exit
(可能是间接致电)std::longjmp
,您不应该使用)如果您不执行上述任何操作,则行为将不确定。如果您不想执行1.,那么您的选择是2.或3.。中止并退出将终止该过程。可以抓一掷,但未抓一掷将导致std::abort
。
请注意,只是因为找不到值,所以不一定无法返回某些值。您可以做的是返回一个表示“未找到”的“前哨”值。例如,返回索引的std::string
函数在没有结果时将返回std::string::npos
。返回指针的函数可能会返回null,而返回迭代器的函数将在范围的末尾返回一个迭代器。
如果没有可以为哨兵保留的返回类型表示形式,则可以通过将返回类型包装成其他状态来添加此类表示形式。标准库为此提供了一个通用包装器:std::optional
。
另一个包装器是建议的std::expected
(据我所知,该标准尚未被接受,但是有许多非标准的实现)。它允许存储有关未返回正确值的原因的信息,这与您可以对异常进行的操作类似。
P.S。您的功能似乎与std::find_if
几乎相同。尽可能使用标准算法。如果搜索空间很大,还要考虑一种对搜索更有效的数据结构。