C++11 lambda表达式不能捕获map/unordered_map值

先看一道面试题。

某公司中有N名员工,给定所有员工工资的清单,财务人员要按照持定的顺序排列员工的工资,他按照工资的频次降序排列,即给定清单中所有频次较高的工资将在频次较低的工资之前出现,如果相同数量的员工都有相同的工资,则将按照给定清单中该工资第一次出现的顺序排列。

写一算法来帮助财务人员排列员工工资的顺序。

输入:
该函数/方法的输入包括两个参数——
num,一个整数,表示员工的人数。
salaries,一个正整数列表,表示N名员工的工资。

输出:
返回一个正整数列表, 该列表按照员工工资的频次排序。

约朿条件:
1 <= num <= 10^5
1 <= salaries[i]<=10^9
0 <= i < num

示例如下
输入:
num=19
salaries=[10000,20000,40000,30000,30000,30000,40000,20000,50000,50000,50000,50000,60000,60000,60000,70000,80000,90000,100000]

输出:
[50000,50000,50000,50000,30000,30000,30000,60000,60000,60000,20000,20000,40000,40000,10000,70000,80000,90000,100000]
 

代码:

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

vector<int> salaryfrequeny(int num, int *salaries)
{
	unordered_map<int, int> cntm;
	unordered_map<int, int> posm;
	vector<int> res;
	vector<pair<int, int>>cntv;
	for (int i = 0; i < num; i++) {
		if (cntm.find(salaries[i]) != cntm.end()) {
			cntm[salaries[i]]++;
		}
		else {
			cntm[salaries[i]] = 1;
			posm[salaries[i]] = i;
		}
	}
	for (auto iter = cntm.begin(); iter != cntm.end(); iter++) {
		cntv.push_back(make_pair(iter->first, iter->second));
	}
	
	/* sort(cntv.begin(), cntv.end(), [posm](const pair<int, int>&x, const pair<int, int>&y) ->int {return (x.second > y.second) || (x.second == y.second && posm.at(x.first) < posm.at(y.first)); }); */
	sort(cntv.begin(), cntv.end(), [&posm](const pair<int, int>&x, const pair<int, int>&y) ->int {return (x.second > y.second) || (x.second == y.second && posm[x.first] < posm[y.first]); });
	for (auto iter = cntv.begin(); iter != cntv.end(); iter++) {
		for (int i = 0; i < iter->second; i++) {
			res.push_back(iter->first);
		}
	}
	return res;
}

发现将lambda的捕获修改为[posm],即如下传值就报错:

sort(cntv.begin(), cntv.end(), [posm](const pair<int, int>&x, const pair<int, int>&y) ->int {return (x.second > y.second) || (x.second == y.second && posm[x.first] < posm[y.first]); });

报错信息如下:

但我这里一开始声明的posm不是const啊,怎么回事?

原来是lambda表达式搞的鬼,当捕获为map/unordered_map的值时,lambda表达式会默认转换为const map/const unordered_map。但又为什么会这样转换呢?

我查看了下C++标准:

map和unordered_map下的operator[],当关键字不存在则会进行插入,这样当有关键字不存在时就会修改了posm的值,所以当捕获为map/unordered_map的值时,lambda表达式干脆默认转换为const map/const unordered_map。这样编译器就会报错了。

另外,当捕获为map/unordered_map的值时,可以使用at(),即

sort(cntv.begin(), cntv.end(), [posm](const pair<int, int>&x, const pair<int, int>&y) ->int {return (x.second > y.second) || (x.second == y.second && posm.at(x.first) < posm.at(y.first)); });

 

posted @ 2018-09-15 22:59  Adano1  阅读(499)  评论(0编辑  收藏  举报