上一个程序初步简单的实现了使用自定义operator的方式的map的初始化,但是遇到了一个问题:
检查operator函数时报“invalid operator<”错误,程序崩了。下午找出原
因。下一个程序中解决该问题,并实现高内聚。
“invalid operator<”错误的原因是(具体见这里):
在待排序列中如果出现相等元素,则会报错Expression : invalid operator <
原因是,c++编译器检测到调用cmp的参数a==b时,c++编译器会立即用反序参数调用cmp函数,即调用cmp(b,a),来判断cmp函数是否已经执行了严格的弱序规则(a与b相等则位置不被改变)
于是,重新实现operator中的条件判断及返回值,这两点就是解决问题的关键。调试通过,程序能正常运行。
// Practice6_map_sort_by_comparator.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include <map> #include <string> #include <iostream> using namespace std; typedef struct tagStudentInfo { int stuId; string stuName; }StudentInfo; /* 两种方式实现操作符函数,一种是struct,另一种是class加public struct CompareStu { int operator()(const StudentInfo &x, const StudentInfo &k) const { if(k.stuId > x.stuId) return 1;//这里必须是大于,并且return true,原因见参考链接 else return x.stuName.compare(k.stuName) > 0; } };*/ /* 另一种是class加public class CompareStu { public: int operator()(const StudentInfo &x, const StudentInfo &k) const { if(k.stuId > x.stuId) return 1;//这里必须是大于,并且return true,原因见参考链接 else return x.stuName.compare(k.stuName) > 0; } };*/ /* 上面的两种实现在使用for循环insert数据时是有问题的,主要在于两元素相等时的返回值,下面这种可编译通过*/ class CompareStu { public: int operator()(const StudentInfo &x, const StudentInfo &k) const { if(k.stuId != x.stuId) return k.stuId > x.stuId;//这里必须是大于,并且return true,原因见参考链接 else return k.stuName.compare(x.stuName) > 0; } }; /* 第一种初始化方式*/ void initMap( map<StudentInfo, int, CompareStu> &mapStu) { StudentInfo studentInfo; studentInfo.stuId = 1; studentInfo.stuName = "student_one"; mapStu.insert(pair<StudentInfo, int>(studentInfo, 90)); studentInfo.stuId = 2; studentInfo.stuName = "student_two"; mapStu.insert(pair<StudentInfo, int>(studentInfo, 80)); } string strs[5] = {"huawei", "xiaomi", "meizu", "oppo", "vivo"}; /* 第二种初始化方式*/ void initMapByPair(map<StudentInfo, int, CompareStu> &mapStu, unsigned int size) { StudentInfo si = {0, ""}; //两种方式实现StudentInfo的初始化,一种是先声明后赋值,另一种直接在循环中初始化。不能混用!!为啥?? for(unsigned int i = 0; i < size; i++) { si.stuId = i + 1; si.stuName = strs[i]; mapStu.insert(pair<StudentInfo, int>(si, i + 90)); } } void printMap(map<StudentInfo, int, CompareStu> mapStu) { map<StudentInfo, int, CompareStu>::iterator iter= mapStu.begin(); for(; iter != mapStu.end(); iter++) { cout << iter->first.stuId << "," << iter->first.stuName << "," << iter->second << endl; } } int main() { map<StudentInfo, int, CompareStu> mapStudent; //initMap(mapStudent); initMapByPair(mapStudent, 5);//第二种初始化方式 printMap(mapStudent); }
运行结果:
1,huawei,90
2,xiaomi,91
3,meizu,92
4,oppo,93
5,vivo,94
Practice6_2_map_sort_by_comparator
原文:http://www.cnblogs.com/liuzc/p/6502497.html