搜尋

首頁  >  問答  >  主體

C++中谓词函数要放在主函数外面吗

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

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

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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

#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;

}

高洛峰高洛峰2824 天前653

全部回覆(1)我來回復

  • 怪我咯

    怪我咯2017-04-17 11:05:46

    函數中定義函數是非法的,你可以:

    1. 將函數定義在外部;
    2. 在函數中,定義一個Functor (需要在函數中定義一個接口體或類, 其實屬於擴展語法,但是主流編譯器都支持);
    3. 使用lambda (C 11, VS2010要打上SP1補丁)。

    使用Functor:

    1

    2

    3

    4

    5

    struct {

        bool operator() (const map_it& lit, const map_it& rit) {

            return lit->second < rit->second;

        }

    } compare;

    使用lambda:

    1

    2

    3

    auto compare = [] (const map_it& lit, const map_it& rit) -> bool {

        return lit->second < rit->second;

    };

    PS: 可以簡寫為:

    1

    2

    3

    auto compare = [] (const map_it& lit, const map_it& rit) {

        return lit->second < rit->second;

    };

    PPS:如果謂詞函數其它地方用不上,並且謂詞函數很簡短:

    1

    2

    3

    sort(itvec.begin(), itvec.end(), [] (const map_it& lit, const map_it& rit) {

        return lit->second < rit->second;

    });

    若對C 11的lambda感興趣,請利用搜索引擎獲取更多知識。
    如果你想讓程序有更好的兼容性,推薦使用Functor方式。

    回覆
    0
  • 取消回覆