C ++如何修复输出向量不清除的错误,如果它与输出向量相同?

时间:2014-07-08 14:43:45

标签: c++ vector

我有一个有两个矢量参数的函数。它只需要“输入向量”中的一些元素,并将它们添加到“输出向量”中。它看起来像这样:

void foo(const std::vector< MyObj >& myObjsIn, std::vector< MyObj >& myObjsOut)
{
  for (size_t i = 0; i < myObjsIn.size(); i++)
  {
    if (myObjsIn[i].condition())
    {
      myObjsOut.push_back(myObjsIn[i]);
    }
  }
}

但如果我给出与输入和输出相同的向量(它在向量的末尾添加所选元素),则存在一个错误。如果我添加清除输出一个,它将清除输入一个(对于指定的情况);所以我得到一个空的矢量。我想到了:

void foo(const std::vector< MyObj >& myObjsIn, std::vector< MyObj >& myObjsOut)
{
  std::vector< MyObj > tmpObjs = myObjsIn;
  myObjsOut.clear();

  for (size_t i = 0; i < tmpObjs.size(); i++)
  {
    if (tmpObjs[i].condition())
    {
      myObjsOut.push_back(tmpObjs[i]);
    }
  }
}

但是可以将输入向量复制到临时向量并清除输出向量吗?是否更好地返回输出向量并创建一个临时向量来添加所选元素?像这样:

std::vector< MyObj > foo(const std::vector< MyObj >& myObjsIn)
{
  std::vector< MyObj > tmpObjs;
  for (size_t i = 0; i < myObjsIn.size(); i++)
  {
    if (tmpObjs[i].condition())
    {
      tmpObjs.push_back(myObjsIn[i]);
    }
  }
  return tmpObjs;
}

或者您建议我做什么,修复该错误并优化我的代码?

2 个答案:

答案 0 :(得分:2)

如果您坚持使用单一用途的功能,那么您的最终答案似乎非常合理。然而另一种选择是临时交换:

void foo(const std::vector< MyObj >& myObjsIn, std::vector< MyObj >& myObjsOut)
{
  std::vector< MyObj > tmpObjs;
  for (size_t i = 0; i < myObjsIn.size(); i++)
  {
    if (myObjsIn[i].condition())
    {
      tmpObjs.push_back(myObjsIn[i]);
    }
  }
  myObjsOut.swap(tmpObjs);
}

可能更优雅的解决方案是利用boost::filter_iteratorhttp://www.boost.org/doc/libs/1_55_0/libs/iterator/doc/filter_iterator.html),然后您可以在ranged-constructor中使用两个过滤器迭代器到新的vector

(未经测试的)代码看起来像这样(当我得到片刻时会尝试编译):

struct execute_condition
{
    bool operator()(const MyObj& obj) const { return obj.condition(); }
};

std::vector filtered_objects(boost::make_filter_iterator<execute_condition>(myObjsIn.begin(), myObjsIn.end()), boost::make_filter_iterator<execute_condition>(myObjsIn.end(), myObjsIn.end()));

答案 1 :(得分:0)

由于您在输出向量上调用push_back,因此您应该更改的唯一内容是循环中的停止条件,因此您将消除无限运行并保持原始功能

void foo(const std::vector< MyObj >& myObjsIn, std::vector< MyObj >& myObjsOut)
{
  size_t inSize = myObjsIn.size();
  for (size_t i = 0; i < inSize; i++)
  {
    if (myObjsIn[i].condition())
    {
      myObjsOut.push_back(myObjsIn[i]);
    }
  }
}