Abhi
Abhi

Reputation: 31

How to find an element in a vector?

I have defined a structure Coord as

struct Coord { 
int x;
int y;
int z; 
};

Overloaded operator!= for Coord

bool Coord::operator !=(Coord& crd)const {
if(this->x != crd.x)
{
    if(this->y != crd.y)
    {
        if(this->z != crd.z)
            return true;
        else
            return false;
    }
    else
        return false;
    return true;
}
else
    return false;
}

Then initialized a vector variable as

vector<Coord> vcoord;

Now I am using following code to get index of vector having a perticular Coord object

int Index::getVIndex(Coord crd) { 
vector<Coord>::iterator it;
int indx;

it = vcoord.begin();
while(it != vcoord.end() && (*it) != crd)
    ++it;

indx = distance(vcoord.begin(),it);
cerr << (*it).x << " " << (*it).y << " " << indx << endl;
return indx;
}

But the value of indx is always 0. Kindly help to get correct result.

Upvotes: 0

Views: 153

Answers (3)

juanchopanza
juanchopanza

Reputation: 227390

You need a not-equals operator for your Coord struct in order to be able to do this:

(*it) != crd

The logic of your not-equals operator is incorrect. The best and easiest option is to provide an equality comparison and use std::find:

struct Coord { 
int x;
int y;
int z; 
};

bool operator == (const Coord& lhs, const Coord& rhs)
{
  return lhs.x==rhs.x && lhs.y==rhs.y && lhs.z==rhs.z;
}

You can then implement != in terms of ==, but you don't need it if you use std::find, which uses == by default:

vector<Coord>::iterator it = std::find(vcoord.begin(), vcoord.end(), crd);

Upvotes: 3

Mike Seymour
Mike Seymour

Reputation: 254431

Your != operator returns true only if all coordinates differ; it should return true if any differ. This means your function will return zero if any coordinate of the first element matches the function argument's.

Your version is a long-winded way of writing:

return x != crd.x && y != crd.y && z != crd.z;

when it should be:

return x != crd.x || y != crd.y || z != crd.z;

It may be easier to get the logic correct by implementing it in terms of ==:

bool operator==(Coord const & lhs, Coord const & rhs) {
    return lhs.x == rhs.x && lhs.y == rhs.y && lhs.z == rhs.z;
}
bool operator!=(Coord const & lhs, Coord const & rhs) {
    return !(lhs == rhs);
}

Also, given a definition of ==, you can use std::find rather than rolling your own loop:

auto found == std::find(vcoord.begin(), vcoord.end(), crd);
if (found == vcoord.end()) {
    // Decide what to do if not found.
    // Returning zero is a bad idea, since there's no way distinguish that 
    // from a successful outcome.
} else {
    return std::distance(vcoord.begin(), found);
}

Upvotes: 2

Andriy
Andriy

Reputation: 8594

You incorrectly implemented the logic in the inequality operator. It should be

bool Coord::operator !=(const Coord& crd)const {
  return x != crd.x || y != crd.y || z != crz.z;
}

Your implementation is logically equivalent to

  return x != crd.x && y != crd.y && z != crz.z;

Upvotes: 1

Related Questions