zoukankan      html  css  js  c++  java
  • 没有傲慢也没有偏见

         最近在跨平台编译项目的时候,遇到一个很有意思的问题,关于std::map.erase() 返回参数不一样,跨平台编译失败的问题。由于涉及到不同平台,不同标准的问题。可能很多不成熟的人又该喷微软不遵循标准,自做主张了,下面这篇文章就是为微软申冤的。

    两个平台的标准:
    查看c++文档发现删除迭代器函数
    c++98 标准 erase返回void
    c++11 标准 erase返回iterator
    再看微软的文档:
    和c++11 的标准是一样的

    编译不过的示例代码:
    std::map<int, string> player_map;
    std::map<int, string>::iterator it = player_map.begin();
    for(; it != player_map.end(); ){
        int id = it->first;
        if(id = 10001) {
             it = player_map.erase(it);
        }else{
             ++it;
        }
    }
         在vs2008里编译没任何问题,到gcc里报没有=操作符。

    对标准库的疑惑:
         如果没有返回值,就需要提前将it复制出来,然后指向下一个迭代器,在删除前一个迭代器。这样做也没有问题,但是在执行++it的时候,it的值会为player_map.end() 如果这时,循环内没有判断,并且在后面使用了,就会导致程序崩溃。如果有返回值的话,每次删除it,返回下一个迭代器,只需要执行下面代码即可方便的循环内删除了。
    std::map<int, string> player_map;
    std::map<int, string>::iterator it = player_map.begin();
    for(; it != player_map.end(); ++it){
        int id = it->first;
        if(id = 10001) {
             it = player_map.erase(it);
             continue;
        }
    }
         这样每次++it后,会立即检测是否到end(),后面引用it,便可放心大胆的使用。
         对于返回void的情形,需要更加谨慎小心。
    std::map<int, string> player_map;
    std::map<int, string>::iterator it = player_map.begin();
    std::map<int, string>::iterator delIt = null;
    for(; it != player_map.end(); ++it){
        delIt = it;
        int id = delIt->first;
        if(id = 10001) {
             ++it;
             player_map.erase(delIt);
             continue;
        }
    }
         为啥这样这样写比较好,因为在循环内很可能我们要用到it,如果此次循环it被删了,直接下一轮循环,如果没被删,则此次迭代器可用,如果写在if外部,在it = player_map.end()的时候,并没有被检测到,后面依然不能用it的属性。

        通过上面的三段代码,发现返回下一个迭代器更加合理,因为在循环内删除,需要指向下次迭代器的值。从这些历史的变迁里,微软让我更加敬佩,他们没有盲目的去崇拜或者遵循权威,而是通过自己对技术的理解,修正了标准库的不足。而同样标准库也是知错能改,并没有因为自己的错误,或者自己订立标准库的便利,而固执不变。这正是我们做技术的应给学习的地方:不盲目权威,知错就改。
        
  • 相关阅读:
    用ADO方式连接Excel
    RTX51 tiny系统容易混淆的问题
    学用NHibernate(一)
    Firefox兼容性
    使用WebClient后的Response编码的问题
    学用ASP.NET2.0
    安装CS2.0 Beta2 到SQL2005+Asp.Net2.0下
    AJAXSLT 的bug修正(2)
    Asp.Net开发小技巧
    URL重写,友好的URL
  • 原文地址:https://www.cnblogs.com/riasky/p/3459000.html
Copyright © 2011-2022 走看看