使用std::find()在不成功的搜索中返回一个特定的值而不是0

Returning a particular value instead of 0 in an unsuccessful search using std::find()

本文关键字:一个 find std 不成功 搜索 返回 使用      更新时间:2023-10-16

我想在一个列表中找到一个特定的元素。如果没有找到,我希望返回一个特定的值,比如-1。如何使用std::find() ?

我在这里读到find()返回一个迭代器,指向[first,last)范围内第一个与val相等的元素,如果没有找到这样的元素,函数返回last。

但是这会导致模棱两可的情况:

例如:

如果列表是

0 -> 1 -> 2 -> 3

当我使用

vector<int> v(4);
v.push_back(0);
v.push_back(1);
v.push_back(2);
v.push_back(3);
vector<int>::iterator i;
i = find(v.begin(), v.end(), 4);
//Unsuccessful find, so I want a value, say -1.
cout<<*i<<endl;  //this prints zero during an unsuccessful search
i = find(v.begin(), v.end(), 0);
cout<<*i<<endl;  //this too prints zero which is ambiguous
//because zero was already in my list

如何摆脱这种暧昧的局面?

find的第一次调用返回的是过端迭代器。不能对这个迭代器解引用。你有未定义的行为,因为你这样做与cout<<*i<<endl;。它打印0的事实是无关的。

它不会给出一个模棱两可的情况,因为如果失败,它返回第二个参数的副本。在本例中,它返回v.end()。您应该检查std::find是否成功:

if (i != v.end()) {
  cout<<*i<<endl;
}

您的代码有未定义的行为。如果没有找到该元素,则find将生成第二个传入迭代器的副本,在本例中为v.end()。对end()迭代器的解引用是未定义的行为。

必须测试迭代器,而不是测试值,以确定是否找到了它:

if (i != v.end()) {
   std::cout << *i << "n";
}

函数不会搜索find范围的最后一个元素,因此您可以安全地将返回的迭代器与它进行比较,以了解搜索是否成功。

i = find(v.begin(), v.end(), 4);
//Unsuccessful find, so I want a value, say -1.
if (i != v.end())
   cout << *i << endl;
else
   cout << -1 << endl;

在您的示例中,最后一个元素确实是不可解引用的,但是如果是这种情况,您应该遵循相同的原则。例如,考虑您想要搜索集合的子序列的情况:您将首先选择定义范围的集合的开始和结束条目,例如v.start()v.start()+2:

auto e = v.start()+2;
i = find( v.start(), e, 4);
if (i != e) 
    cout << *i << endl; // will output 4 if found
else
    cout << -1 << endl;

这里e是有效的,但是必须与它进行比较,以确保find返回的结果在搜索范围内

相关文章: