当前位置: 首页 > news >正文

景观石网站建设方案广西seo公司

景观石网站建设方案,广西seo公司,wordpress nginx url,网页视频下载器app免费STL const_iterator等价于指向常量的指针(pointer-to-const)。它们都指向不能被修改的值。标准实践是能加上const就加上,这也指示我们需要一个迭代器时只要没必要修改迭代器指向的值,就应当使用const_iterator。 上面的说法对C11…

STL const_iterator等价于指向常量的指针(pointer-to-const)。它们都指向不能被修改的值。标准实践是能加上const就加上,这也指示我们需要一个迭代器时只要没必要修改迭代器指向的值,就应当使用const_iterator

上面的说法对C++11和C++98都是正确的,但是在C++98中,标准库对const_iterator的支持不是很完整。首先不容易创建它们,其次就算你有了它,它的使用也是受限的。假如你想在std::vector<int>中查找第一次出现1983(C++代替C with classes的那一年)的位置,然后插入1998(第一个ISO C++标准被接纳的那一年)。如果vector中没有1983,那么就在vector尾部插入。在C++98中使用iterator可以很容易做到:

std::vector<int> values;
…
std::vector<int>::iterator it =std::find(values.begin(), values.end(), 1983);
values.insert(it, 1998);

但是这里iterator真的不是一个好的选择,因为这段代码不修改iterator指向的内容。用const_iterator重写这段代码是很平常的,但是在C++98中就不是了。下面是一种概念上可行但是不正确的方法:

typedef std::vector<int>::iterator IterT;               //typedef
typedef std::vector<int>::const_iterator ConstIterT;std::vector<int> values;
…
ConstIterT ci =std::find(static_cast<ConstIterT>(values.begin()),  //caststatic_cast<ConstIterT>(values.end()),    //cast1983);values.insert(static_cast<IterT>(ci), 1998);    //可能无法通过编译,//原因见下

typedef不是强制的,但是可以让代码中的cast更好写。(你可能想知道为什么我使用typedef而不是条款9提到的别名声明,因为这段代码在演示C++98做法,别名声明是C++11加入的特性)

之所以std::find的调用会出现类型转换是因为在C++98中values是non-const容器,没办法简简单单的从non-const容器中获取const_iterator。严格来说类型转换不是必须的,因为用其他方法获取const_iterator也是可以的(比如你可以把values绑定到reference-to-const变量上,然后再用这个变量代替values),但不管怎么说,从non-const容器中获取const_iterator的做法都有点别扭。

当你费劲地获得了const_iterator,事情可能会变得更糟,因为C++98中,插入操作(以及删除操作)的位置只能由iterator指定,const_iterator是不被接受的。这也是我在上面的代码中,将const_iterator(我那么小心地从std::find搞出来的东西)转换为iterator的原因,因为向insert传入const_iterator不能通过编译。

老实说,上面的代码也可能无法编译,因为没有一个可移植的从const_iteratoriterator的方法,即使使用static_cast也不行。甚至传说中的牛刀reinterpret_cast也杀不了这条鸡。(它不是C++98的限制,也不是C++11的限制,只是const_iterator就是不能转换为iterator,不管看起来对它们施以转换是有多么合理。)不过有办法生成一个iterator,使其指向和const_iterator指向相同,但是看起来不明显,也没有广泛应用,在这本书也不值得讨论。除此之外,我希望目前我陈述的观点是清晰的:const_iterator在C++98中会有很多问题,不如它的兄弟(指iterator)有用。最终,开发者们不再相信能加const就加它的教条,而是只在实用的地方加它,C++98的const_iterator不是那么实用。

 所有的这些都在C++11中改变了,现在const_iterator既容易获取又容易使用。容器的成员函数cbegincend产出const_iterator,甚至对于non-const容器也可用,那些之前使用iterator指示位置(如inserterase)的STL成员函数也可以使用const_iterator了。使用C++11 const_iterator重写C++98使用iterator的代码也稀松平常:

std::vector<int> values;                                //和之前一样
…
auto it =                                               //使用cbeginstd::find(values.cbegin(), values.cend(), 1983);    //和cend
values.insert(it, 1998);

现在使用const_iterator的代码就很实用了!

唯一一个C++11对于const_iterator支持不足(译注:C++14支持但是C++11的时候还没)的情况是:当你想写最大程度通用的库,并且这些库代码为一些容器和类似容器的数据结构提供beginend(以及cbegincendrbeginrend等)作为非成员函数而不是成员函数时。其中一种情况就是原生数组,还有一种情况是一些只由自由函数组成接口的第三方库。(译注:自由函数free function,指的是非成员函数,即一个函数,只要不是成员函数就可被称作free function)最大程度通用的库会考虑使用非成员函数而不是假设成员函数版本存在。

举个例子,我们可以泛化下面的findAndInsert

 

template<typename C, typename V>
void findAndInsert(C& container,            //在容器中查找第一次const V& targetVal,      //出现targetVal的位置,const V& insertVal)      //然后在那插入insertVal
{using std::cbegin;using std::cend;auto it = std::find(cbegin(container),  //非成员函数cbegincend(container),    //非成员函数cendtargetVal);container.insert(it, insertVal);
}

它可以在C++14工作良好,但是很遗憾,C++11不在良好之列。由于标准化的疏漏,C++11只添加了非成员函数beginend,但是没有添加cbegincendrbeginrendcrbegincrend。C++14修订了这个疏漏。

如果你使用C++11,并且想写一个最大程度通用的代码,而你使用的STL没有提供缺失的非成员函数cbegin和它的朋友们,你可以简单的写下你自己的实现。比如,下面就是非成员函数cbegin的实现:

template <class C>
auto cbegin(const C& container)->decltype(std::begin(container))
{return std::begin(container);   //解释见下
}

你可能很惊讶非成员函数cbegin没有调用成员函数cbegin吧?我也是。但是请跟逻辑走。这个cbegin模板接受任何代表类似容器的数据结构的实参类型C,并且通过reference-to-const形参container访问这个实参。如果C是一个普通的容器类型(如std::vector<int>),container将会引用一个const版本的容器(如const std::vector<int>&)。对const容器调用非成员函数begin(由C++11提供)将产出const_iterator,这个迭代器也是模板要返回的。用这种方法实现的好处是就算容器只提供begin成员函数(对于容器来说,C++11的非成员函数begin调用这些成员函数)不提供cbegin成员函数也没问题。那么现在你可以将这个非成员函数cbegin施于只直接支持begin的容器。

如果C是原生数组,这个模板也能工作。这时,container成为一个const数组的引用。C++11为数组提供特化版本的非成员函数begin,它返回指向数组第一个元素的指针。一个const数组的元素也是const,所以对于const数组,非成员函数begin返回指向const的指针(pointer-to-const)。在数组的上下文中,所谓指向const的指针(pointer-to-const),也就是const_iterator了。 

回到最开始,本条款的中心是鼓励你只要能就使用const_iterator。最原始的动机——只要它有意义就加上const——是C++98就有的思想。但是在C++98,它(译注:const_iterator)只是一般有用,到了C++11,它就是极其有用了,C++14在其基础上做了些修补工作。

请记住:

  • 优先考虑const_iterator而非iterator
  • 在最大泛型代码中,优先考虑非成员函数版本的beginendrbegin等,而非同名成员函数

http://www.mmbaike.com/news/91272.html

相关文章:

  • 免费b2b网站大全全职高手关键词检测工具
  • 把自己做的网站开放到外网高级seo培训
  • 可以做淘宝店铺开关灯网站收录查询 站长工具
  • 做纺织生意用什么网站好上优化seo
  • 做网站上是外部连接怎么改教育机构加盟
  • 好的学习网站打广告营销策划培训
  • 多与pR值高的网站做链接长春做网络优化的公司
  • 做推广要知道的网站微信怎么推广自己的产品
  • 做网站需要哪些证书百度seo在哪里
  • 域名交易网站股票发行ipo和seo是什么意思
  • wordpress中文语言排名优化系统
  • 南京做网站询南京乐识2023网站seo
  • 理卖做各视频网站的会员泉州seo技术
  • 搭建什么样的平台重庆做seo外包的
  • 七牛云存储 wordpress 缩略图seo自动优化软件安卓
  • 手机网站制作推广定制爱站网工具
  • 外贸网站建设 杭州阿里指数官网
  • 美食网站案例网站快速有排名
  • 高端网站建设开发市场调研的内容
  • 网站建设价格评审资料清单网页seo是什么意思
  • 表格布局网站推广产品的方法和步骤
  • 互动科技 网站珠海网站建设
  • 电商网站项目经验介绍搜索历史记录
  • 中铁雄安建设有限公司网站盘古百度推广靠谱吗
  • 新网站如何做优化推广方案怎么做
  • 网站内的搜索是怎么做的深圳网站seo推广
  • 烟台免费做网站网址查询地址查询
  • 如何免费自己做个网站营销号
  • 网页设计短板图片南京seo
  • 用web开发一个网站怎么做个人seo外包