简体   繁体   中英

For a search algo with reference return type, what should be the default return value?

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.

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

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.

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;
}

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()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM