【问题标题】:Checking if an item is already in a vector [closed]检查一个项目是否已经在一个向量中[关闭]
【发布时间】:2014-01-16 16:51:02
【问题描述】:

所以我想对类中的向量进行一些错误检查,以查看该项目是否已经存在,然后再将新项目添加到向量中。

A 类 cpp

void ClassA::func(std::shared_ptr<ClassB> new_item)
{
    for(auto items : vector_)
    {
        if(items = new_item)
        {
            return;
        }
        vector_.push_back(new_item);
    }
}

vector_ 是成员类成员 std::vector。使用此当前实现,所有 new_item 都将被忽略,即使它不是重复项。我知道 'if(items = new_item)' 是有问题的行,但我不知道为什么。

【问题讨论】:

  • 首先,尝试使用== 而不是=。接下来看看std::find
  • 这不是有未定义的行为,因为push_back 可能会重新分配,然后基于范围的 for 循环使用的迭代器将无效?更不用说它会多次添加新项目。
  • 应该使用 const 迭代器、const 和参数的另一个原因。当您打算阅读时(在您的情况下进行比较)。如果你使用了 const 迭代器,你就不会在这里发布这个问题 :)
  • 你应该使用std::set,而不是std::vector

标签: c++ vector shared-ptr


【解决方案1】:

您在这里分配而不是比较相等性:

if(items = new_item) // assigns value of new_item to items

通过使用经过良好测试的标准库函数,例如std::find,可以轻松避免此类问题:

#include <algorithm> // for std::find
....
if (find(vector_.begin(), vector_.end(), newitem) == vector_.end())
  vector_.push_back(newitem);

【讨论】:

    【解决方案2】:

    你有一个错字:

    if(items = new_item)
    

    应该是

    if (items == new_item)
    

    顺便说一句,你可以写

    if (std::find(std::begin(vector_), std::end(vector_), new_item) == std::end(vector_) {
        vector_.push_back(new_item);
    }
    

    或使用std::set

    【讨论】:

      【解决方案3】:

      = 是赋值

      == 是相等的

      你想要

          if(items == new_item)
          {
              return;
          }
      

      【讨论】:

        【解决方案4】:

        这是你需要的:

        void ClassA::func(std::shared_ptr<ClassB> new_item)
        {
            for(auto items : vector_)
            {
                if(items == new_item)
                {
                    return;
                }            
            }
        
            vector_.push_back(new_item);
        }
        

        请注意,您需要== 而不是=。此外,您的代码在每次迭代时都将new_item 添加到向量中。现在如果没有找到该项目,它就完成了。

        【讨论】:

        • 你可能也想做auto const&amp;
        • 他需要的是if ( std::find( vector_.begin(), vector_end(), new_item ) == vector_.end() ) { vector_.push_back( new_item ); }。重新实现标准库中已有的内容是没有意义的。 (他还需要另一个命名约定。下划线作为前导或尾随字符都不好。)
        • @JamesKanze - 是的,但我试图说明代码有什么问题
        • @JamesKanze:我不明白这有多糟糕。我这样做是为了更轻松地识别类的私有成员。
        • 这样会有工作的好处,但仍然效率低。
        【解决方案5】:

        你正在使用

         if(items = new_item)
            {
                return;
            }
        

        new_item 的值被分配给项目,因为“=”是一个赋值运算符,任何对 if 为正的东西都会使条件为真。您需要使用“==”运算符进行比较

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2010-12-22
          • 1970-01-01
          • 1970-01-01
          • 2011-04-17
          • 1970-01-01
          • 1970-01-01
          • 2014-03-30
          相关资源
          最近更新 更多