为何std::lower_bound算法无法用于std::map,但其成员函数可行?
算法库的std::lower_bound函数接受前向迭代器并返回下界,在vector中可正常使用,但用于std::map时会出现编译错误。明明std::map支持双向迭代器,而双向迭代器可作为前向迭代器使用,为何调用std::lower_bound(map.begin(), map.end(), int值)无法生效,而std::map的成员函数map.lower_bound(int值)却能正常工作?
参考示例代码:
#include<bits/stdc++.h> using namespace std; int main(){ vector<int>v = {1,1,1,2,3,4,2,3,2,5,6,12,12,9}; map<int,int>mp; for(auto x:v)mp[x]++; for(int i=0;i<15;i++){ auto it = mp.lower_bound(i); // 可以正常运行 // auto it = lower_bound(mp.begin(),mp.end(),i) // 编译错误 if(it!=mp.end()) cout<<i<<" lower bound is "<<it->first<<" and its frequency in vector is "<<it->second<<endl; } return 0; }
原因解析:
元素类型不匹配:全局
std::lower_bound默认会直接比较迭代器指向的元素和你传入的第三个参数。但std::map的迭代器指向的是std::pair<const int, int>类型的键值对,你传入的第三个参数是int类型,C++没有默认规则来比较pair<int,int>和int,所以编译报错。而map的成员lower_bound是容器专属实现,它知道要拿传入的键值和map中元素的键做比较,不需要传入完整的键值对。实现逻辑与效率差异:全局
std::lower_bound如果用双向迭代器(比如map的迭代器),只能做O(n)的线性遍历;而map的成员lower_bound基于红黑树结构实现,直接通过树的特性在O(log n)时间内找到下界,效率高得多,这也是容器提供专属成员函数的核心原因。可选解决方案(用全局函数):如果你一定要用全局
std::lower_bound,可以手动指定比较函数,明确告诉它用键值对的键来和传入的int比较:auto it = lower_bound(mp.begin(), mp.end(), i, [](const pair<int, int>& elem, int key) { return elem.first < key; });这样就能让全局函数正确执行,编译通过。
内容的提问来源于stack exchange,提问作者Shivam Tanwar

