模板参数类型,仿函数


今天在写一个C++程序的时候,要用到STL的set容器,而且我想让它利用自定义的排序准则来实现自动排序。而且set中元素类型是指向自定义的结构体的指针。结果运行总是出错。


下面先贴出起初的代码:

  1. #include <iostream>  
  2. #include <set>  
  3.   
  4. using namespace std;  
  5.   
  6. typedef struct test_t{  
  7.     int a;  
  8.     int b;  
  9. }test;  
  10.   
  11. class PersonalCriterion{  
  12. public:  
  13.     bool operator()(const test* &obj1,const test* &obj2){  
  14.         return obj1->a < obj2->a;  
  15.     }  
  16. };  
  17.   
  18. int main(){  
  19.     set<test*,PersonalCriterion> myset;  
  20.     test* obj1 = new test();  
  21.     obj1->a = 10;  
  22.     obj1->b = 9;  
  23.     test* obj2 = new test();  
  24.     obj2->a = 5;  
  25.     obj2->b = 9;  
  26.   
  27.     myset.insert(obj1);  
  28.     myset.insert(obj2);  
  29.   
  30.     return 0;  
  31. }  

结果在VS2008中编译运行出错,错误信息如下:



显然问题出在这个自定义的仿函数排序准则这里。那么究竟是什么问题呢?错误信息显示这里丢失了限定符,即const。但是我这里参数上明明有const呀,疑惑!


再次仔细看输出的错误信息,不能将参数一从类型1转化到类型2.这两个类型有什么区别呢?答案是const的位置不同:指针常量和常量指针的区别!在有指针的地方,const放在不同的位置会导致完全不同的结果。前一种类型中,const是来修饰指针本身的,即指针常量,它指向的对象确定了之后就不能修改了,即不能修改使得它指向另外一个对象。而第二种类型,const是来修饰指针所指向的类型的,即常量指针,指针本身不是const的,可以修改指向别的对象。但是指针所指向的地址处的内容却不能修改,它是const的。



接下来就可以对代码进行修改了。为了避免出现上述的问题,我们用typedef重新定义了指向自定义结构体的指针类型:



这样就不会出现原来的问题了。修改正确的代码如下:

  1. #include <iostream>  
  2. #include <set>  
  3.   
  4. using namespace std;  
  5.   
  6. typedef struct test_t{  
  7.     int a;  
  8.     int b;  
  9. }test;  
  10.   
  11. typedef test* test_ptr;  
  12.   
  13. class PersonalCriterion{  
  14. public:  
  15.     bool operator()(const test_ptr &obj1,const test_ptr &obj2){  
  16.         return obj1->a < obj2->a;  
  17.     }  
  18. };  
  19.   
  20. int main(){  
  21.     set<test_ptr,PersonalCriterion> myset;  
  22.     test_ptr obj1 = new test();  
  23.     obj1->a = 10;  
  24.     obj1->b = 9;  
  25.     test_ptr obj2 = new test();  
  26.     obj2->a = 5;  
  27.     obj2->b = 9;  
  28.     test_ptr obj3 = new test();  
  29.     obj3->a = 20;  
  30.     obj3->b = 48;  
  31.     test_ptr obj4 = new test();  
  32.     obj4->a = 1;  
  33.     obj4->b = 2;  
  34.     test_ptr obj5 = new test();  
  35.     obj5->a = 3;  
  36.     obj5->b = 39;  
  37.   
  38.     myset.insert(obj1);  
  39.     myset.insert(obj2);  
  40.     myset.insert(obj3);  
  41.     myset.insert(obj4);  
  42.     myset.insert(obj5);  
  43.   
  44.     set<test_ptr,PersonalCriterion>::iterator iter;  
  45.     for (iter = myset.begin();iter != myset.end();++iter)  
  46.     {  
  47.         cout << (*iter)->a << endl;  
  48.     }  
  49.   
  50.   
  51.     return 0;  
  52. }  

运行结果:



参考资料:

http://www.cppblog.com/cc/archive/2006/03/12/4045.html


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值