如何正确处理函数是否退出而不会引起返回错误

时间:2019-04-10 10:02:54

标签: c++

我有一个搜索向量的函数,如果找到了该项,则将其返回。但是我想知道最好的软件方法来处理,如果找不到的话。

我创建了一个函数,可以返回-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];
    }
}

如果遇到要搜索的项目不在矢量中的情况,则程序将退出。

4 个答案:

答案 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();
}

进一步检查是否退回了endend指示是否找到该值。

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)

有三种退出函数的方法:

  1. 返回值
  2. 抛出一个值
  3. 致电std::abortstd::exit(可能是间接致电)
  4. ({std::longjmp,您不应该使用)

如果您不执行上述任何操作,则行为将不确定。如果您不想执行1.,那么您的选择是2.或3.。中止并退出将终止该过程。可以抓一掷,但未抓一掷将导致std::abort

请注意,只是因为找不到值,所以不一定无法返回某些值。您可以做的是返回一个表示“未找到”的“前哨”值。例如,返回索引的std::string函数在没有结果时将返回std::string::npos。返回指针的函数可能会返回null,而返回迭代器的函数将在范围的末尾返回一个迭代器。

如果没有可以为哨兵保留的返回类型表示形式,则可以通过将返回类型包装成其他状态来添加此类表示形式。标准库为此提供了一个通用包装器:std::optional

另一个包装器是建议的std::expected(据我所知,该标准尚未被接受,但是有许多非标准的实现)。它允许存储有关未返回正确值的原因的信息,这与您可以对异常进行的操作类似。


P.S。您的功能似乎与std::find_if几乎相同。尽可能使用标准算法。如果搜索空间很大,还要考虑一种对搜索更有效的数据结构。