Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

returning c++ iterators

I have a function that returns an iterator if an object is found.

Now i have a problem. How do i fix the problem of informing the object that called this function that the object was not found?

vector<obj>::iterator Find(int id, int test)
{
        vector<obj>::iterator it;
            aClass class;

            for(it = class.vecCont.begin(); it != class.vecCont.end(); ++it)
            {
               if(found object) //currently in psuedo code
               return it;
            }

            return ???? // <<< if not found what to insert here?

}

Do i need to change my data structure in this instead?

Thanks in advance! :)

like image 547
mister Avatar asked May 09 '12 19:05

mister


2 Answers

Return vector::end(), throw an exception, or return something other than a plain iterator

Better yet, don't implement your own Find function. That is what the <algorithm> library is for. Based on your psudocode, you can probably use std::find or std::find_if. find_if is particularly useful in cases where equality doesn't necessarily mean operator==. In those cases, you can use a [C++11] lambda or if C++11 isn't available to you, a functor class.

Since the functor is the lowest common denominator, I'll start with that:

#include <cstdlib>
#include <string>
#include <algorithm>
#include <vector>
#include <functional>
using namespace std;

class Person
{
public:
    Person(const string& name, unsigned age) : name_(name), age_(age) {};

    string name_;
    unsigned age_;
};

class match_name : public unary_function <bool, string>
{
public:
  match_name(const string& rhs) : name_(rhs) {};
  bool operator()(const Person& rhs) const
  {
    return rhs.name_ == name_;
  }
private:
    string name_;
};

#include <iostream>

int main()
{
    vector<Person> people;
    people.push_back(Person("Hellen Keller", 99));
    people.push_back(Person("John Doe", 42));

    /** C++03 **/
    vector<Person>::const_iterator found_person = std::find_if( people.begin(), people.end(), match_name("John Doe"));

    if( found_person == people.end() )
        cout << "Not FOund";
    else
        cout << found_person->name_ << " is " << found_person->age_;
}

found_person now points to the person whose name is "John Doe", or else points to people_.end() if that person wasn't found.

A C++11 lambda is new language syntax that makes this process of declaring/defining a functor and using is somewhat simpler for many cases. It's done like this:

string target = "John Doe";
vector<Person>::const_iterator found_person = std::find_if(people.begin(), people.end(), [&target](const Person& test) { return it->name_ == target; });
like image 148
John Dibling Avatar answered Sep 19 '22 22:09

John Dibling


You can return an iterator to the end, i.e. return class.vecCont.end() to indicate that.

like image 35
Eitan T Avatar answered Sep 18 '22 22:09

Eitan T