0

我想使用find_iffrom #include <algorithm>,但问题是它无法识别向量是否为空。

假设以下代码段

typedef std::vector< std::pair<int , int > > myVector;
myVector aVector;
struct equal: std::unary_function< std::pair<int , int >,bool >
{
  equal(const int &aNum) : theNum(aNum) {}
  bool operator()(const std::pair<int , int > &arg) const { return arg.first == theNum; }
  const int &theNum;
};
...

void check_and_insert(int num) {
   myVector::iterator it = find_if( aVector.begin(), aVector.end(), equal(num));
   if (it == aVector.end())
     aVector.push_back( std::make_pair(num, 1) );
   else
     ++dit->second;
}

假设aVector为空。我看到结果find_if不是aVector.end(),所以它else是错误的。这是 find_if 的工作方式吗?这很奇怪,但我可以通过插入第一个元素来解决这个问题:

if (aVector.empty()) {
  aVector.push_back( std::make_pair(num, 1) );
  return;
}
// find_if...

这是唯一的解决方案吗?有没有更好的主意?

更新 如评论中所述, find_if 工作正常。该错误是aVector由另一个函数中的引用调用修改的。感谢所有帮助,抱歉打扰

4

4 回答 4

3

错误在您的代码中,因为按照标准:

返回: [first,last) 范围内满足以下相应条件的第一个迭代器 i:*i == value、pred(*i) != false、pred(*i) == false。如果没有找到这样的迭代器,则返回 last。

于 2013-06-17T10:51:07.773 回答
1

由于评论太长,这里是一个使用与您使用的相同仿函数的示例:

#include <functional>
#include <utility>

struct equal: std::unary_function< std::pair<int , int >,bool >
{
  equal(const int &aNum) : theNum(aNum) {}
  bool operator()(const std::pair<int , int > &arg) const 
  { 
    return arg.first == theNum; 
  }
  const int &theNum;
};

#include <iostream>
#include <vector>
#include <algorithm>
int main()
{
  typedef std::vector< std::pair<int , int > > myVector;
  myVector aVector;
  int num = 42;
  myVector::iterator it = find_if( aVector.begin(), aVector.end(), equal(num));
  std::cout << std::boolalpha;
  std::cout << (it==aVector.end()) << std::endl;
}

输出

真的

这似乎反驳了你问题的前提。

于 2013-06-17T11:06:33.787 回答
0

Assume aVector is empty. I see that result of find_if is not aVector.end()

Here you have a contradiction. If you pass an begin(), end() on empty vector that's empty range and end() will get returned from find_if immediately.

于 2013-06-17T11:00:26.577 回答
0

在这个示例测试代码中,与的比较vector::end()似乎工作正常(VS2010 SP1):

#include <algorithm>
#include <vector>
#include <iostream>
using namespace std;

int main()
{
    vector<int> v;
   /*   
    v.push_back(11);
    v.push_back(22);
    v.push_back(33);
   */ 

    auto it = find_if(v.begin(), v.end(), [](int x){ return (x % 2) == 1; } );    

    if (it != v.end())
        cout << *it;
    else
        cout << "Not found.";

    cout << endl;
}

输出:

未找到。


编辑

在评论部分,您要求测试您的代码片段。实际上,您的代码片段不是可编译的片段,因此如果您希望其他人对其进行测试,我建议您将来提供可编译的代码片段。

无论如何,我尝试调整您的原始代码,例如使用VS2010 SP1 中提供的一些方便的C++11功能,如lambdas(而不是仿函数)或auto.

这个测试代码有效:

#include <algorithm>
#include <iostream>
#include <utility>
#include <vector>
using namespace std;

typedef vector<pair<int, int>> MyVector;

void CheckAndInsert(MyVector& aVector, int num) 
{
    auto it = find_if( 
        aVector.begin(), aVector.end(), 
        [=](const std::pair<int, int>& elem)
        {
            return elem.first == num;
        }
    );

    if (it == aVector.end())
    {
        cout << "*** EMPTY VECTOR*** (num == " << num << ")\n";

        aVector.push_back( make_pair(num, 1) );
    }
    else
    {
        ++(it->second);
    }
}

int main()
{
    MyVector aVector;

    CheckAndInsert(aVector, 1);
    CheckAndInsert(aVector, 1);
    CheckAndInsert(aVector, 2);
    CheckAndInsert(aVector, 3);
    CheckAndInsert(aVector, 4);
    CheckAndInsert(aVector, 3);

    for (auto it = aVector.begin(); it != aVector.end(); ++it)
    {
        cout << "(" << (it->first) << ", " << (it->second) << ")\n";
    }
}

输出:

*** EMPTY VECTOR*** (num == 1)
*** EMPTY VECTOR*** (num == 2)
*** EMPTY VECTOR*** (num == 3)
*** EMPTY VECTOR*** (num == 4)
(1, 2)
(2, 1)
(3, 2)
(4, 1)

作为旁注,您也可以考虑使用 astd::map<int, int>而不是std::vector<std::pair<int, int>>.

于 2013-06-17T10:54:04.663 回答