C++标准模板库向量问题
有人能用英语解释一下这是怎么回事吗?
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);
}
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);
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
@mlimber 已经给出了一种解释。
我会以不同的方式解释它。用简单的英语来说,这是一种采用非常简单的东西的方法:
使其变慢(线性而不是对数)并且相当难以阅读或理解。
编辑:公平地说,我想我应该补充一点,您可能想要做这样的事情有一些原因。例如,如果您确实需要知道
Cat
添加到集合中的顺序,则保留原始顺序可能有意义。同样,如果您通常以受益于它们在内存中连续的方式使用集合,并且很少添加新项目,那么可能更有意义将数据存储在向量
中而不是集合
中。然而,
set
的设计目的是完全执行这里所做的事情,因此set
是显而易见的选择(没有令人信服的理由来使用向量
在您所显示的内容中不可见)。@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:
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 avector
than anset
.A
set
, however, is designed to do exactly what's being done here, so aset
is the obvious choice (absent compelling reasons to use avector
that just aren't visible in what you've shown).如果向量中还没有一个名为
morris
的项目,它会将其添加到向量cats
中!std::find
用于检查项目morris
是否在向量cats
中。它没有,std::find
返回的值将等于cats.end()
。在此之后,其他一切都非常简单。It adds an item called
morris
to the vectorcats
IF the vector doesn't already has it!The
std::find
is used to check if the itemmorris
is in the vectorcats
or not. It doesn't has,std::find
returned value would be equal tocats.end()
. After this, everything else is pretty much straight forward.假设代码是正确的(例如 morris 的类型和初始化以及使用指针进行比较),重点是查看 morris 是否在 cats 集合中,如果不是,则将其添加到其中。
Assuming the code is correct (like the type and initialization of morris and using pointers for your comparison), the point is to see if morris is in the collection of cats, and if not, to add him to it.
cats 是指向 Cat 对象的指针向量,而不是 Cat 对象的向量。
这会搜索 cats(cats.begin() 到 cats.end()) 的全部范围,以查找等于 morris
std::find(cats.begin(), cats.end 的对象(指向 cat 的指针) (), morris)
如果找到了,返回值是指向指向对象的向量的迭代器;如果没有找到,则返回结束迭代器(cats.end())。考虑到这一点,这个:
if (std::find(cats.begin(), cats.end(), morris) == cats.end())
是一个测试,看看是否 cats包含该对象(莫里斯)。如果没有,则执行:
cats.push_back(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.
首先要小心:你的评论是错误的。 cats 不是 Cat 对象的向量,而是指向 cat 对象的指针的向量。
现在,语句:
std::find(cats.begin(), cats.end(), morris)
意味着您在名为 morris 的地方有一个 Cat* 。该语句将在两个提供的迭代器(即 cats.begin() 和 cats.end() )之间搜索向量,以查找指向 Cat 的指针,等于 morris (相同地址)。如果找不到, std::find 返回第二个迭代器,因此,在您的情况下为“cats.end()”
因此“if (std::find(cats.begin(), cats.end(), morris) = = cats.end()) { cats.push_back(morris); }" 的意思是,用简单的英语来说,“如果 morris 尚未在 cats 向量中,则将其放在末尾”
我很难说得更具体如果我们不知道到底是什么在困扰您
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 (i.e : 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
你错了。
cats
是指向Cat
类的指针的std::vector
。有一个区别:Cat
驻留在堆栈中,是通过操作创建的,不必删除。如您的示例中所示,指针是由创建的
,并且在您使用完指针后必须将其删除,然后再丢弃指针:
我现在将在您的示例中添加一些代码:
这将创建一个动态分配的对象
morris<堆上
Cat
类型的 /code>。然后,使用std::find
在向量cats
中搜索新创建的对象,在该代码片段中总是会失败。如果 std::find 失败,它会返回一个迭代器,指向容器中最后一个元素之后的元素(这正是 std::vector::end() 的作用)返回)。因此,如果未找到morris
,代码将在向量后面创建一个新元素并将morris
添加到其中。You get that wrong.
cats
is astd::vector
of pointers to the classCat
. There's a difference:Cat
s reside on the stack, are created by doingand do not have to be deleted. Pointers as in your example, are created by
and have to be deleted once you're done with it before you throw away the pointer:
I will now add a little code to your example:
This creates a dynamically allocated object
morris
of typeCat
on the heap. Then,std::find
is used to search the vectorcats
for the newly created object, which will always fail in this code fragment. Ifstd::find
fails, it returns an iterator to the element one past the last element in the container (which is exactly whatstd::vector::end()
returns). So ifmorris
is not found, the code will create a new element at the back of the vector and addmorris
to it.