【问题标题】:C++ standard template library vector questionC++标准模板库向量题
【发布时间】:2011-07-08 07:19:51
【问题描述】:

谁能用英语解释一下这里发生了什么?

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

【问题讨论】:

    标签: c++ vector standard-library


    【解决方案1】:

    @mlimber 已经给出了一种解释。

    我会以不同的方式解释它。用简单的英语来说,这是一种非常简单的方式:

     std::set<Cat> cats;
    
     cats.insert(morris);
    

    并使其变慢(线性而不是对数)并且相当难以阅读或理解。

    编辑:公平地说,我想我应该补充一点,可能想要做这样的事情的几个原因。例如,如果您确实需要知道 Cats 添加到集合中的顺序,那么保留原始顺序可能会有意义。同样,如果您通常以一种受益于它们在内存中连续的方式使用集合,并且仅很少添加新项目,则可能更有意义将数据存储在vector 而不是set

    然而,set 旨在完成完全这里正在做的事情,因此 set 是显而易见的选择(没有令人信服的理由来使用 vector,这只是' t 在您显示的内容中可见)。

    【讨论】:

    • +1 对我从不使用 std::set 感到羞耻 - 现在我会的,谢谢你指出这一点(不应该是 std::set 吗?)跨度>
    • 所以插入一个集合会检查它是否已经不存在?
    • @sol:是的。 set::insert(t):“当且仅当容器中没有与 t 的键等效的元素时插入 t。”在set的情况下,key就是对象。
    【解决方案2】:

    如果向量还没有它,它会向向量 cats 添加一个名为 morris 的项目!

    std::find 用于检查项目morris 是否在向量cats 中。它没有,std::find 返回值将等于cats.end()。在此之后,其他一切都非常简单。

    【讨论】:

      【解决方案3】:

      假设代码是正确的(比如 morris 的类型和初始化以及使用指针进行比较),关键是查看 morris 是否在猫的集合中,如果没有,则将他添加到其中。

      【讨论】:

        【解决方案4】:

        cats 是指向 Cat 对象的指针向量,而不是 Cat 对象的向量。

        这会在所有猫(cats.begin() 到 cat.end())中搜索等于 morris 的对象(指向猫的指针)

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

        如果找到,返回值是指向指向对象的向量的迭代器,如果没有找到,则返回结束迭代器(cats.end())。考虑到这一点,这是:

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

        是测试猫是否包含该对象(莫里斯)。如果没有,则执行以下操作:

        cats.push_back(morris);

        将对象(morris)放入向量中。

        【讨论】:

          【解决方案5】:

          首先要小心:您的评论是错误的。 cat 不是 Cat 对象的向量,而是指向 cat 对象的 POINTERS 向量。

          现在,声明:

          std::find(cats.begin()、cats.end()、莫里斯)

          暗示你在某个地方有一只猫*,叫做莫里斯。该语句将在两个提供的迭代器(即: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 还没有在 cat 向量中,把它放在最后"

          如果我们不知道究竟是什么困扰着您,我将很难说得更具体

          【讨论】:

            【解决方案6】:
            std::vector<Cat*> cats; //I get that cats is a vector of Cat objects
            

            你弄错了。 cats 是一个 std::vector 指向类 Cat 的指针。有区别:Cats 驻留在栈上,是通过做来创建的

            Cat morris;
            

            并且不必删除。在您的示例中,指针由

            创建
            Cat* morris = new Cat();
            

            在你扔掉指针之前必须删除它:

            delete morris;
            

            我现在将在您的示例中添加一些代码:

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

            这会在堆上创建一个Cat 类型的动态分配对象morris。然后,std::find 用于在向量cats 中搜索新创建的对象,在此代码片段中总是会失败。如果std::find 失败,它将返回一个迭代器,指向容器中最后一个元素之后的元素(这正是std::vector::end() 返回的内容)。所以如果没有找到morris,代码会在vector后面创建一个新元素,并在里面添加morris

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2015-02-17
              • 1970-01-01
              • 2014-06-14
              • 1970-01-01
              • 2016-03-17
              • 2011-05-03
              • 2011-09-30
              相关资源
              最近更新 更多