简体   繁体   中英

C++ standard template library vector question

Can someone explain in English what is going on here?

std::vector<Cat*> cats; //I get that cats is a vector of Cat objects

if (std::find(cats.begin(), cats.end(), morris) == cats.end()) {
   cats.push_back(morris);
}

@mlimber has already given one explanation.

I'd explain it a bit differently. In plain English, it's a way of taking something really simple:

 std::set<Cat> cats;

 cats.insert(morris);

and making it slower (linear instead of logarithmic) and considerably harder to read or understand.

Edit: In fairness, I suppose I should add that there are a few reasons you might want to do something like this. For example, if you really need to know the order in which Cat s were added to the collection, preserving the original order might make some sense. Likewise, if you're usually using the collection in a way that benefits from them being contiguous in memory, and only rarely adding a new item, it might make more sense to store the data in a vector than an set .

A set , however, is designed to do exactly what's being done here, so a set is the obvious choice (absent compelling reasons to use a vector that just aren't visible in what you've shown).

It adds an item called morris to the vector cats IF the vector doesn't already has it!

The std::find is used to check if the item morris is in the vector cats or not. It doesn't has, std::find returned value would be equal to cats.end() . After this, everything else is pretty much straight forward.

假设代码是正确的(例如morris的类型和初始化,并使用指针进行比较),重点是看morris是否在猫的集合中,如果不是,则将其添加到猫中。

cats is a vector of pointers to Cat objects, not a vector of Cat objects.

This searches the full range of cats(cats.begin() through cats.end()) for an object(pointer to cat) that is equal to morris

std::find(cats.begin(), cats.end(), morris)

The return value is an iterator into the vector pointing to the object if it was found, and it returns the end iterator(cats.end()) if it was not found. With that in mind, this:

if (std::find(cats.begin(), cats.end(), morris) == cats.end())

is a test to see if cats contains that object(morris). And if it doesn't, then it executes this:

cats.push_back(morris);

which puts the object(morris), into the vector.

First be carefull : your comment is wrong. cats isn't a vector of Cat objects, but a vector of POINTERS to cat objects.

Now, the statement :

std::find(cats.begin(), cats.end(), morris)

implies you have a Cat* somewhere called morris. This statement is going to search the vector, between the two provided iterators (ie : cats.begin() and cats.end() ) for a pointer to Cat, equall to morris (same address). If none is found, std::find returns the second iterator, so, in your case "cats.end()"

Therefore "if (std::find(cats.begin(), cats.end(), morris) == cats.end()) { cats.push_back(morris); }" means, in plain english "if morris isn't already in the cats vector, put it at the end"

I'll have a hard time being more specific if we don't know what's bothering you exactly

std::vector<Cat*> cats; //I get that cats is a vector of Cat objects

You get that wrong. cats is a std::vector of pointers to the class Cat . There's a difference: Cat s reside on the stack, are created by doing

Cat morris;

and do not have to be deleted. Pointers as in your example, are created by

Cat* morris = new Cat();

and have to be deleted once you're done with it before you throw away the pointer:

delete morris;

I will now add a little code to your example:

Cat* morris = new Cat();

if (std::find(cats.begin(), cats.end(), morris) == cats.end()) {
   cats.push_back(morris);
}

This creates a dynamically allocated object morris of type Cat on the heap. Then, std::find is used to search the vector cats for the newly created object, which will always fail in this code fragment. If std::find fails, it returns an iterator to the element one past the last element in the container (which is exactly what std::vector::end() returns). So if morris is not found, the code will create a new element at the back of the vector and add morris to it.

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