Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/138.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何处理;“未找到项目”;查找函数中的情况?_C++ - Fatal编程技术网

C++ 如何处理;“未找到项目”;查找函数中的情况?

C++ 如何处理;“未找到项目”;查找函数中的情况?,c++,C++,我经常遇到需要以某种方式报告查找项目失败的情况。因为有很多方法来处理这种情况,我总是不知道该怎么做。以下是几个例子: class ItemCollection { public: // Return size of collection if not found. size_t getIndex(Item * inItem) { size_t idx = 0; for (; idx != mItems.size(); ++idx)

我经常遇到需要以某种方式报告查找项目失败的情况。因为有很多方法来处理这种情况,我总是不知道该怎么做。以下是几个例子:

class ItemCollection
{
public:

    // Return size of collection if not found.
    size_t getIndex(Item * inItem)
    {
        size_t idx = 0;
        for (; idx != mItems.size(); ++idx)
        {
            if (inItem == mItems[idx])
            {
                return idx;
            }
        }
        return idx;
    }


    // Use signed int and return -1 if not found.
    int getIndexV2(Item * inItem)
    {            
        for (int idx = 0; idx != mItems.size(); ++idx)
        {
            if (inItem == mItems[idx])
            {
                return idx;
            }
        }
        return -1;
    }

    // Throw exception if not found.
    size_t getIndexV3(Item * inItem)
    {
        for (size_t idx = 0; idx != mItems.size(); ++idx)
        {
            if (inItem == mItems[idx])
            {
                return idx;
            }
        }
        throw std::runtime_error("Item not found");
    }

    // Store result in output parameter and return boolean to indicate success. 
    bool getIndex(Item * inItem, size_t & outIndex)
    {
        for (size_t idx = 0; idx != mItems.size(); ++idx)
        {
            if (inItem == mItems[idx])
            {
                outIndex = idx;
                return true;
            }
        }
        return false;
    }


private:
    std::vector<Item*> mItems; 
};
类项目集合
{
公众:
//如果未找到,则返回集合的大小。
大小\u t获取索引(项*inItem)
{
大小\u t idx=0;
对于(;idx!=mItems.size();++idx)
{
if(inItem==mItems[idx])
{
返回idx;
}
}
返回idx;
}
//使用带符号的int,如果找不到,则返回-1。
int getIndexV2(项*inItem)
{            
对于(int idx=0;idx!=mItems.size();++idx)
{
if(inItem==mItems[idx])
{
返回idx;
}
}
返回-1;
}
//如果未找到,则抛出异常。
大小\u t获取索引xv3(项目*inItem)
{
对于(size_t idx=0;idx!=mItems.size();++idx)
{
if(inItem==mItems[idx])
{
返回idx;
}
}
抛出std::运行时_错误(“未找到项”);
}
//将结果存储在输出参数中,并返回布尔值以指示成功。
bool getIndex(项目*初始、大小和索引)
{
对于(size_t idx=0;idx!=mItems.size();++idx)
{
if(inItem==mItems[idx])
{
outinex=idx;
返回true;
}
}
返回false;
}
私人:
病媒螨;
};

在我(年轻的)编程生涯中,我曾经使用过所有这些。我主要使用“返回集合大小”方法,因为它类似于STL迭代器的工作方式。然而,我想在未来做出更明智的选择。那么,关于如何处理未发现错误的决策应该基于什么样的设计原则呢?

我认为这取决于您正在搜索的内容的上下文。这是关键信息吗?如果信息很关键,则需要抛出异常,尤其是如果不这样做会导致进一步的错误

如果没有找到匹配项,我喜欢return-1,因为您总是知道如果没有找到匹配项,该函数将返回什么。如果您根据收集的大小进行计算,那么您将永远无法确切知道返回的内容


我也不太喜欢在输出参数中返回它,因为它有点复杂,你必须问问自己,这样的函数是否真的需要增加复杂性

我采用的一条经验法则是:

当有疑问时,按照STL所做的去做

std::find
返回序列末尾以外的迭代器


决定是否抛出异常或返回某种错误值的问题可能很困难。只有较高级别的代码才知道某件事情是否异常,但必须由较低级别的代码做出决定。

一般来说,我不会在任何情况下使用您的第一个和第四个示例。IMO,返回集合大小的通信不够清晰,以至于找不到任何项(以一个错误为准)。我认为不需要返回两个输出,只要返回一个即可(如
-1=ItemNotFound

使用其余两种方法取决于程序中的具体情况。如果物品应该在你的收藏中,这种情况是例外。在这种情况下,抛出异常就可以了

另一方面,如果物品可能在您的收藏中,这是一种常规情况,因此例外情况并不充分

如果您正在编写一个可能在这两种情况下都使用的函数,则不应抛出异常。由于您永远不知道什么时候可能需要一个函数,而不是您第一次想到的上下文,所以我的建议是为未找到的项返回-1。您还可以对其他函数采用这种方法,从而使代码库更加一致

我主要使用“返回集合大小”方法,因为它类似于STL迭代器的工作方式


迭代器,如果您使用这些作为访问器/变异器,则基于算法的迭代器将返回一个超过集合末尾的迭代器(您可以将其与
coll.end()进行比较)
。在我看来,这绝对是件好事。

您的函数比算法头中任何基于迭代器的函数都更相似。它返回的是索引,而不是迭代器

我不喜欢您的函数返回集合大小以模拟“结束后的一个”。它要求调用方知道集合大小以检查函数是否成功。我更喜欢您的第二个函数,因为它返回一个始终表示“未找到”的常量值
std::string
类型通过返回值来组合这两种类型,该值为-1,但为无符号类型

不要使用第三个函数的异常方法,除非您有其他函数调用它,它会提前告诉您是否会找到该项。也就是说,为调用者提供一些避免异常的方法


当返回的索引即使在找不到项的情况下也很有用时,您的第四个函数最为合适。如果您正在进行二进制搜索,则了解在集合中找到项的位置的索引可能会很有用。然后您可以提供一个
insert
函数,该函数接受该值作为提示,如。如果无法提供此类信息,则不要使用此类函数,因为调用方使用此类函数更麻烦。请选择第一种样式。

使用类似boost.optional的功能

阅读以下内容,了解其背后的理念,以及如何亲自实施:

它也是c
std::pair<size_t,bool>

class ItemCollection
{
public:
    typedef std::pair<size_t,bool> RC;
    // Return size of collection if not found.
    RC getIndex(Item * inItem)
    {
        size_t idx = 0;
        for (; idx != mItems.size(); ++idx)
        {
            if (inItem == mItems[idx])
            {
                return RC(idx,true);
            }
        }
        return RC((-1),false);
    }
class ItemCollection
{
    static int const npos = -1;

    .....

    int getIndexV2(Item * inItem)  // returns npos on failure.

};