了解std :: map :: find

时间:2017-07-04 19:04:51

标签: c++ c++11

我正在尝试学习如何将std :: map与函数一起使用。我对std::map::find在这方面的工作方式感到有些困惑。这是一个简单的代码,我使用Lambda函数和map。

auto Lambda = [](const int&a, const int& b) {
 cout << "\n Inside lambda \n";
 return a < b;
 };

std::map<int, int, decltype(Lambda)> expt(Lambda);
expt[1] = 2;
expt[10] = 12;
auto search1 = expt.find(1);
auto search10 = expt.find(10);
if(search1 != expt.end()) {
    std::cout << "Found " << search1->first << " " << search1->second << '\n';
}
else {
    std::cout << "Not found\n";
}

以下是我得到的输出:

Inside lambda
Inside lambda
Inside lambda
Inside lambda
Inside lambda
Inside lambda
Inside lambda
Found 1 2

我对find在这种情况下的实际工作方式感到有些困惑。为什么我得到7次lambda函数调用,即使我的地图中只有2个键?

2 个答案:

答案 0 :(得分:5)

operator <无法告诉你两件事情是一致的。您需要同时调用x < yy < x才能验证x == y。因此,每次map实际找到一个键时,它会将参数和找到的键两次进行比较,一次正常,一次交换。

这导致lambda(1,1)lambda(10,10)出现两次。

对于lambda(10,1)lambda(1,10)插入密钥为10的元素时,这是必需的,因为map 可能必须调用比较两次,当它找不到一个键时(插入的交换顺序来看那个)。

答案 1 :(得分:2)

让我试着解决这个问题:

这里的要点是:你提供'&lt;'的定义仅在地图构造函数中操作。 Map需要对'&lt; ='操作进行perofrm,它显然是这样的:

bool le(left, rigth){
  return (left<right) and not (rigth<left);
}

所以它有时只能做一个<,有时在地图上进行单个操作需要2个。

  1. 前两次比较是由插入操作引起的。映射算法必须确定新元素是否是现有元素<=。它执行2 <次比较以找出(new<old and old>new)。 (请注意,如果先插入10,然后再插入1,则只能进行一次比较,因为它们中的第一个new<old会产生明确的结果(true)。)
  2. 出于同样的原因,第一个find执行lambda 2次。第一个检查<返回false,因此它需要执行第二个检查,使用交换的参数来了解值是否相等。
  3. 再一次,同样的故事......