C++中谓词函数要放在主函数外面吗
高洛峰
高洛峰 2017-04-17 11:03:46
0
1
647

在c++中定义了一个谓词函数:compare,用在sort函数中。但如果我将compare写在主函数中,在编译阶段编译器(我用的是VS2010)会报错,提示

error C2601: “compare”: 本地函数定义是非法的。

将函数定义在外部就运行正常。
想问一下这是为什么。谓词函数必须在主函数外面定义吗?还有什么函数需要定义在主函数外?
错误程序如下:

#include <iostream>
#include <map>
#include <string>
#include <vector>
#include <algorithm>

using namespace std;

//typedef map<string, int>::const_iterator map_it;
//定义谓词
//bool compare(const map_it& lit,const map_it& rit){
//		return lit->second < rit->second;
//	}

int main()
{
	string s;	
	map<string, int> counters;	
	typedef map<string, int>::const_iterator map_it;
	bool compare(const map_it& lit,const map_it& rit){
		return lit->second < rit->second;
	}

	while(cin >> s){
		++counters[s];
	}	

	//将map iterator存入vector,进行排序
	vector<map_it> itvec;
	for(map_it it = counters.begin(); it != counters.end(); ++it){
		itvec.push_back(it);
	}

	sort(itvec.begin(),itvec.end(),compare);

	for(vector<map_it>::const_iterator vit = itvec.begin(); vit != itvec.end(); ++vit)
	{
		cout<<(*vit)->first<<" occurs "<<(*vit)->second<<" times"<<endl;
	}
	return 0;
}
高洛峰
高洛峰

拥有18年软件开发和IT教学经验。曾任多家上市公司技术总监、架构师、项目经理、高级软件工程师等职务。 网络人气名人讲师,...

reply all(1)
刘奇

It is illegal to define functions within functions. You can:

  1. Define the function externally;
  2. In the function, define a Functor (you need to define an interface body or class in the function, which is actually an extended syntax, but is supported by mainstream compilers);
  3. Use lambda (C 11, VS2010 requires SP1 patch).

Use Functor:

struct {
    bool operator() (const map_it& lit, const map_it& rit) {
        return lit->second < rit->second;
    }
} compare;

Use lambda:

auto compare = [] (const map_it& lit, const map_it& rit) -> bool {
    return lit->second < rit->second;
};

PS: It can be abbreviated as:

auto compare = [] (const map_it& lit, const map_it& rit) {
    return lit->second < rit->second;
};

PPS: If the predicate function is not used elsewhere and the predicate function is very short:

sort(itvec.begin(), itvec.end(), [] (const map_it& lit, const map_it& rit) {
    return lit->second < rit->second;
});

If you are interested in C 11 lambda, please use the search engine to get more knowledge.
If you want your program to have better compatibility, it is recommended to use the Functor method.

Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template