Reputation: 207
Say I have an array, and I want to retrieve a reference to an element of this array.
struct A {
int n;
}
A& search_algo(A* AList, int len, int target) {
for (int i = 0; i < len; i++) {
if (AList[i].n == target) { return AList[i]; }
}
return what? //problem comes here, target not in array, what should I return
}
I would like to know what is the most conventional way to deal with it, or what return value makes the most sense. Like how can I best convey a message of "your thing isn't here, go away". Something similar to a nullptr
would be great.
My current solution is to initialize a object A
on the stack and return it. Although I can compile just fine, but returning a reference to local variable is unsafe.
I am thinking initializing the object on heap using new
but that would be messy and I will have to deal with memory release. I don't like it.
Upvotes: 0
Views: 91
Reputation: 111
Return index would be a good practice. But if you insist on reference, I think you can throw an exception at the end of search_algo.
Upvotes: 1
Reputation: 3442
If you are expecting "not found" as a valid result, you should not return a reference to the found object, as there is no "null" reference in C++.
You may return a pointer (nullptr for not found), an iterator (one-past-the-last for not found).
In the standard library, a function which returns a reference is usually not for searching an element, and it is usually an exceptional case when there is not element to return. So it would just throw an exception, such as std::map::at()
Upvotes: 0
Reputation: 1444
A good practice is to return the index/position where the element is found, instead of returning the found value. This is what STL
does, it returns the position/iterator of the found element and if the element is not found, it returns the position 1 unit ahead of the last element which indicates that the element is not found in the container. You can return len
if the element is not found in the array. For example,
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
struct A {
int n;
};
int search_algo(A* AList, int len, int target) {
for (int i = 0; i < len; i++)
if (AList[i].n == target)
return i;
return len;
}
int main(){
int _len = 4;
A _list[_len] = {6,7,8,9};
int idx1 = search_algo(_list,_len,7);
int idx2 = search_algo(_list,_len,10);
if(idx1==_len)
cout<<"Element not found"<<endl;
else
cout<<"Element found at "<<idx1<<" index and it's value is "<<_list[idx1].n<<endl;
if(idx2==_len)
cout<<"Element not found"<<endl;
else
cout<<"Element found at "<<idx2<<" index and it's value is "<<_list[idx2].n<<endl;
}
Output:
Element found at 1 index and it's value is 7
Element not found
Upvotes: 1
Reputation: 343
Return the last() iterator of the container or len
to indicate failure of find(). This is the convention of STL and a good practice.
template<typename InputIterator, typename T>
InputIterator find (InputIterator first, InputIterator last, const T& val)
{
while (first!=last) {
if (*first==val) return first;
++first;
}
return last;
}
Upvotes: 0