我是微软的STL维护人员,我们再一次有一年的工作要告诉你。 (““我们”指的是P.J.Plauger的大多数功能,我自己的大多数修复和库问题解决方案,加上我们的库开发负责人Artur Laksberg和我们的CRT维护人员James McNellis提供的修复。)
如果你错过了 公告 ,你可以 下载VS14 CTP1 现在(注意他们说“在虚拟机中,或者在可用于重新格式化的计算机上”)和vs14rtm “最有可能在2015年某个时候上市” .
请注意,在这篇文章中,我将介绍2013 RTM和VS14 CTP1之间的变化——也就是说,这里列出的内容是VS14 CTP1中的新功能。 (例如, 编号3656 “makeu unique(修订版1)”在2013 RTM中发布,因此此处未列出。)
此外,“CTP”代表“社区技术预览”,但它的意思是 “阿尔法” . 请通过 微软连接 .
STL特征
我们已经实现了以下功能,这些特性被投票到C++ 14,加上一个技术规范:
编号3642
编号3644 空正向迭代器
编号3654 引用()
编号3657 异构关联查找
编号3658 整数u序列
编号3668 交换()
N3670型 获取
编号3671 双范围equal()/isu permutation()/mismatch()
编号3779 <复杂>UDL
编号3887 元组元素
N3940号 文件系统“V3”技术规范
请注意,由于缺少编译器支持,
还要注意,我们的
此外,我们已经实现了以下的库问题解决方案,这些问题被投票到C++ 14:
LWG 2097型 应约束打包的任务构造函数
LWG 2104型 唯一锁定移动分配不应为noexcept
长荣2112 无法从派生的用户定义类
长荣2144 类型索引中缺少noexcept规范
LWG 2145型 错误类别默认构造函数
长荣2162 分配器u属性::最大u大小缺少noexcept
LWG 2174型 wstringu convert::converted()应为noexcept
LWG 2176型 服务提供商wstringu convert和wbufferu convert的特殊成员
长荣2187 向量
LWG 2193型 标准库容器的默认构造函数是显式的
长荣2247 类型特征和标准::nullptr
长荣2268 在std::basicu string的成员函数assign的声明中设置默认参数
长荣2272 引用应该使用charu traits::eq进行字符比较
长荣2278 标准库类型的用户定义文本
长荣2285 生成反向迭代器
长荣2306 匹配结果::引用应为值类型&,而不是常量值类型&&
长荣2315 弱ptr应可移动
长征2324 插入迭代器构造函数应使用addressof()
长荣2329 带有匹配结果的regexu match()/regexu search()应禁止临时字符串
长荣2332 regex_iterator/regex_token_iterator应该禁止临时regex
长荣2339 第n元素中的措辞问题
长荣2344 quoted()与padding的交互不清楚
长荣2346 积分常数的成员函数应标记为noexcept
国标9 删除gets()
noexcept的故事有点复杂。 我们有内部的NO.No.Office和(不用于公共消费的)宏(当前不限于公共消费),它扩展到“抛出”(这又由编译器作为对Y-O-DESPECEC(NoFoPE)的同义词处理,与C++的98- 14的“抛出())标准语义不同。 这些宏应该扩展到No.Buffe,但是我们已经被一系列相对较小的编译器错误所阻止,主要涉及C++ 14的隐式NOT规则,而不是析构函数。 (由于STL的实现本身就很复杂并且应用广泛,因此它是对编译器特性的严格测试。) 好消息是,这些编译器错误已经被修复,我已经能够在下一批更改中将STL的宏切换到使用真正的noexcept(STL的所有测试都通过了)。 不幸的是,这在VS14 CTP1中不可用。 (此外,我们还在解决条件noexcept的问题,STL应该在一些地方使用它。 目前,我们的宏将扩展为零。)
至于GETSH(),它从C11和C++ 14中删除(注:C++ 14仍然包含C99标准库,但是从C11作为一个特殊的例外进行了这个改变),我们的CRT的
我们还实现了一个优化,由编译器后端团队的ericbrumer提供。 编译器的自动矢量化非常喜欢高度对齐的内存,因此我们将std::allocator更改为自动返回高度对齐的内存以进行大的分配,在这种情况下,它可能会以最小的开销来交换不同的内存。 如果您好奇,我们目前使用的神奇数字是,我们将为4096字节或更大的分配激活此特殊行为,并将它们(至少)与32字节(256位)对齐,尽管我们绝对保留在将来对此进行修改的权利。 (目前,我们正在为x86和x64做这项工作,但没有为ARM做这项工作—由于在该平台上的过度一致性,我们还没有观察到性能优势。) 请注意,为了避免不匹配的噩梦,不能禁用此行为–无论您是否要求编译器自动矢量化,甚至发出AVX/etc.指令,都会激活此行为。
STL修复
当我写关于 VC 2013中的STL修复 继续在这里申请。 说到这里,在我写了那篇文章之后,我能够在2013 RTM中得到更多的修复,但是我从来没有找到时间回去更新那篇文章。 因此,为了完整起见,2013 RTM中提供的以下修复程序:std::bind()现在使用限定调用std::tie(),以避免与boost::tie()(DevDiv#728471)混淆/ 接#792163 ),并且std::函数的构造函数现在可以避免在内存不足时崩溃(DevDiv#748972)。
此外,我们认为我们已经修复了iostreams中的错误,它是错误的浮点,但在2013年RTM之前不久,我们发现了一个回归并恢复了更改。 我们正在为VS14再次研究这个问题,但是我们仍然意识到这个领域的问题。
现在,让我们看看VS14 CTP1中提供的修复程序。 我们有一个p进行了几次大修:
*时钟有几个问题。 高分辨率时钟不是高分辨率(DevDiv#349782/ 连接#719443 )稳定的时钟和CRT的时钟()不稳定/ 接#753115 ). 我们已经解决了这个问题,将高分辨率时钟作为稳定时钟的typedef(在标准允许的情况下),它现在由QueryPerformanceCounter()提供支持,这是高分辨率的,并且满足标准对稳定/单调性的要求。 因此,staid_clock::time_point现在是chrono::time_point
*
没有特定顺序的单个修复:
*C++ 11的最小分配器接口是非常棒的,但是这意味着STL实现必须做额外的工作,以处理缺少C++ 03的冗长分配器接口(例如嵌套的ReBe结结构)的用户定义的分配器。 在2013年RTM(多亏了可变模板)中,我们完成了使最小分配器适应详细接口所需的机制,但我们并没有在整个STL中始终使用它(DevDiv#781187)/ 接#800709 ). 所以对于vs14ctp1,我们审核了整个STL并修复了所有问题,所以现在任何需要分配器的东西都将接受最小的接口。 值得注意的是,std::function、sharedu ptr/allocateu shared()和basicu string是固定的。
*多亏了Filesystem V3,我们现在可以处理形式为serverdirectoryfilename.txt(DevDiv#512571)的网络路径/ 接#770316 第706628页/ 连接#788976 ).
*
*STL现在支持 /Gv编译器选项 (/Gd、/Gr和/Gz已经得到支持),以及显式标记为u vectorcall(DevDiv#793009)的函数/ 接#804357 ). 我们通过在/Gv下包含所有STL头来验证前者。 对于后者,uu vectorcall将在uu stdcall/etc.工作的任何地方工作,而不是在任何地方(由一个单独的bug跟踪,仍然处于活动状态)。
*STL现在支持 /Zc:strictStrings编译器选项 (德夫迪夫784218)。 C++ 03允许(但ISO不可)从字符串文字转换为可修改的字符**。 C++ 11移除了这个转换,//ZC:StultStand强制执行这个禁止。 虽然/Zc:strictStrings当前默认处于关闭状态,但我强烈建议使用它。
*2006年,
*结合襄樊的编译器修复,我们改变了STL的头文件,通过避免释放未使用的机器(DevDiv#888567),大大减少了对象文件的大小(和静态库的大小)/ 连接#820750 ). 这种未使用的机器通常被链接器丢弃,因此EXE/DLL的大小应该保持不变(尽管它们可能会经历一些小的改进)。 例如,当编译一个文件(对于x86/MD /O2),包括所有C和C++标准库头并与之无关,VS 2013发出731 KB对象文件,而VS14 CTP1发出小于1 KB。
*C++ 11要求STL实现容忍操作员的过载地址。 VS2013的容器做到了,但不是所有的算法(DevDiv#758134)/ 接#797008 ). 此外,STL实现需要容忍重载的逗号运算符(“因为没有什么禁止它们”),这对于采用用户定义的迭代器并在for循环中使用“++iter1,++iter2”之类内容的算法来说是有问题的(DevDiv#758138)/ 接#797012 ). 我们已经审核了所有STL算法,以及迭代器强度的所有排列,以解决/comma问题。 我们已经修复了所有这些问题(通过添加一些addressof()调用和eleventy zillion(void)强制转换),并添加了一个测试来确保它们保持不变。
*自2005年以来,我们已经发布了调试检查,检测并抱怨STL算法的无效输入(如转置迭代器)。 然而,它们有点过于激进,抱怨将空指针作为迭代器传递,即使标准说它们完全有效。 例如,将两个[null,null]范围合并到一个null输出是有效的no-op。 我们已经审核了每个STL算法,并修复了它们的调试检查,以接受作为迭代器有效传递的空指针,同时仍然拒绝空指针的无效场景。 (例如,[非null,null)是一个伪范围。) 这解决了长期存在的bug报告(DevDiv#253803/ 接#683214 第420517页/ 接#741478 第859062页/ 接#813652 ).
* C++ 11的二进制搜索算法需要处理异构类型,其中范围元素和给定值的类型可以不同,并且范围元素可能甚至不能互相比较。 我们在几年前修复了下限()和上限(),但错过了相等的范围()(DevDiv#813065)/ 接#807044 ). 我们在EngalSangeReo()中留下了一个C++ 03时代的调试检查,这是有坏的两个原因:(1)它试图验证输入范围是排序的,但是C++ 11不需要元素<元素编译,(2)这是一个对数时间算法的验证,这是一个坏主意! 我们已经删除了违规的调试检查,因此,ErralSangeReo()现在符合C++ 11。 (但是,equal_range()仍包含另一个调试检查。 loweru bound()只给出elem
*我们更新了向量
*我们无序的关联容器不能为单个元素的插入和复制提供有力的保证