VS 2015 RC版本中的C++11/14/17 特性
[原文发表地址] C++11/14/17 Features In VS 2015 RC
[原文发表时间] 2015/04/29 2:00PM
现在, Visual Studio 2015 RC版本已发布,因此是时候来更新RC版本新特性表格了!(这是我之前的博客: VS2015 Preview版本中的核心特性和VS2015 CTP1版本中的STL特性。)
核心语言
VS 2013 |
VS 2015 |
备注 |
|
部分 |
是 |
||
否 |
是 |
||
部分 |
是 |
[RC] |
|
是 |
是 |
||
部分 |
是 |
[RC] |
|
是 |
是 |
||
是 |
是 |
||
是 |
是 |
||
是 |
是 |
||
是 |
是 |
||
是 |
是 |
||
是 |
是 |
||
否 |
否 |
||
是 |
是 |
||
是 |
是 |
||
是 |
是 |
||
是 |
是 |
||
是 |
是 |
||
否 |
是 |
[RTM] |
|
否 |
部分 |
[1] |
|
部分 |
是 |
||
是 |
是 |
||
否 |
是 |
||
是 |
是 |
||
否 |
是 |
||
否 |
是 |
||
是 |
是 |
||
否 |
是 |
[RC] |
|
否 |
是 |
||
是 |
是 |
||
部分 |
是 |
||
是 |
是 |
||
否 |
是 |
||
否 |
是 |
||
否 |
是 |
||
是 |
是 |
||
是 |
是 |
||
是 |
是 |
||
是 |
是 |
||
否 |
是 |
||
C++11 核心语言特性: 并行 |
VS 2013 |
VS 2015 |
备注 |
是 |
是 |
||
是 |
是 |
||
是 |
是 |
||
是 |
是 |
||
是 |
是 |
||
是 |
是 |
||
否 |
是 |
[RTM] |
|
是 |
是 |
||
否 |
是 |
||
是 |
是 |
[2] |
|
部分 |
是 |
||
否 |
是 |
||
C++11 核心语言特性: C99 |
VS 2013 |
VS 2015 |
备注 |
部分 |
是 |
||
部分 |
部分 |
[3] |
|
是 |
是 |
||
N/A |
N/A |
[4] |
|
C++14 核心语言特性 |
VS 2013 |
VS 2015 |
备注 |
是 |
是 |
||
否 |
是 |
||
否 |
是 |
||
否 |
是 |
||
否 |
是 |
||
否 |
否 |
||
否 |
否 |
||
否 |
否 |
||
N/A |
N/A |
[5] |
|
否 |
是 |
[RTM] |
|
否 |
是 |
[RC] |
|
否 |
是 |
[RC] |
|
C++1z (C++17?) 核心语言特性 |
VS 2013 |
VS 2015 |
备注 |
否 |
是 |
[RC] |
|
否 |
否 |
||
否 |
是 |
[RC] |
|
是 |
是 |
||
否 |
否 |
||
否 |
否 |
||
否 |
是 |
[RTM] |
|
否 |
否 |
||
否 |
否 |
||
否 |
否 |
备注:
[RC] 这些特性在Preview 和RC版本之间实现。
[RTM] 这些特性在RC 和RTM版本之间实现。(也就是说RC版本并不支持这些新特性,但是已集成到源代码管理器,将在RTM版本可用。)
[1] 我们已基本实现了全部C++11常量表达式,但是我仍把它列为部分支持,这是因为编译器开发团队仍在修复一些重要bug, 这些bug限制了STL(及其它类库,如Boost库)使用常量表达式。我们期待在RTM build完成这项工作。
(请注意C++14 扩展常量表达式这一特性并不在RTM计划中。这好比,我们在开始星际殖民化之前,需要完成重力飞行测试。)
[2] 之前我被列入负责" Atomics in signal handlers “,现在已不是, 因为尽管已经开始了<atomic>的维护工作, 但是我对“signal handlers”仍一无所知。我们的CRT维护者James McNellis, 研究过这些问题,并将一直致力于此项工作, 我们将回到最初在2012中实现的<atomic >。
[3] 对C99 预处理器的支持不变。 它被标为部分支持是因为尽管编译器支持可变宏, 但是我们的预处理器在很多方面的表现与C99/C++11并不一致。
[4] "扩展整数类型" 被列为不可用是因为(C++)标准允许,但是并不要求支持长度大于于long long的类型。为了与之前保持一致,我们暂时不支持这种类型,
[5] "Avoiding/fusing allocations" 被列为不可用是因为标准允许,但并不要求此项优化。为了与之前保持一致, 我们选择不实现它(至少现在不实现)。
(列为N/A 的特性代表是 或 否,这可能会被误导。)
标准类库
现在,我们来看一下标准库的状态:
*我们的C99标准类库已基本实现,除了tgmath.h 文件(其与C++并不相关)以及和编译指示宏CX_LIMITED_RANGE/FP_CONTRACT。此外, 除了常量表达式,我们已基本实现了C++11 标准类库。(我在2015 RC 中已经实现了nested_exception类。)
* 此外, 除了result_of 和 std::function 中的SFINAE 表达式以及少数类库问题 (我们已修复了标准类库的bug,实现了至少16种标准库) 之外, 我们已实现了全部C++14 标准类库。如下表所列, <shared_mutex>在RC 和RTM之间实现。
* 此外, 除了4个类库问题之外,我们已实现了全部C++17-so-far标准类库 (如工作报告N4431) 。 如下表所列, 我已在RC 和 RTM之间实现工作报告N4089中对unique_ptr<T[]>的修改。
这是一张完整的类库提议表格,该表格已被选入C++14 和C++17标准 (到目前为止):
状态 |
标准 |
文件 |
标题 |
constexpr |
C++14 |
constexpr For <complex> |
|
constexpr |
C++14 |
constexpr For < chrono> |
|
constexpr |
C++14 |
constexpr For <array> |
|
constexpr |
C++14 |
constexpr For <initializer_list>, <tuple>, <utility> |
|
constexpr |
C++14 |
integral_constant::operator()() |
|
constexpr |
C++14 |
Fixing constexpr Member Functions Without const |
|
constexpr |
C++14 |
constexpr For <functional> |
|
SFINAE |
C++14 |
SFINAE-Friendly result_of |
|
VS 2015 |
C++14 |
UDLs For < chrono>, <string> (1729ms, "meow"s, etc.) |
|
VS 2015 |
C++14 |
Null Forward Iterators |
|
VS 2015 |
C++14 |
quoted() |
|
VS 2015 |
C++14 |
Heterogeneous Associative Lookup |
|
VS 2015 |
C++14 |
integer_sequence |
|
2015 RTM |
C++14 |
<shared_mutex> |
|
VS 2015 |
C++14 |
exchange() |
|
VS 2015 |
C++14 |
get<T>() |
|
VS 2015 |
C++14 |
Dual-Range equal(), is_permutation(), mismatch() |
|
VS 2015 |
C++14 |
Sized Deallocation |
|
VS 2015 |
C++14 |
UDLs For <complex> (3.14i, etc.) |
|
VS 2015 |
C++14 |
tuple_element_t |
|
2015 RTM |
C++14 |
Renaming shared_mutex To shared_timed_mutex |
|
VS 2015 |
C++17 |
void_t |
|
2015 RTM |
C++17 |
Safe Conversions In unique_ptr<T[]> |
|
VS 2015 |
C++17 |
invoke() |
|
2015 opt-in |
C++17 |
Removing auto_ptr, random_shuffle(), And Old <functional> Stuff |
|
VS 2015 |
C++17 |
noexceptCleanups |
|
VS 2015 |
C++17 |
uncaught_exceptions() |
|
VS 2015 |
C++17 |
Trivially Copyable reference_wrapper |
|
VS 2015 |
C++17 |
insert_or_assign()/try_emplace() For map/unordered_map |
|
VS 2015 |
C++17 |
size(), empty(), data() |
|
VS 2013 |
C++14 |
Minimal Container Element Requirements |
|
VS 2013 |
C++14 |
Transparent Operator Functors (less<>, etc.) |
|
VS 2013 |
C++14 |
Alias Templates For <type_traits> (decay_t, etc.) |
|
VS 2013 |
C++14 |
make_unique() |
|
N/A |
C++14 |
Discouraging rand() |
|
N/A |
C++17 |
Contiguous Iterators |
备注:
[constexpr] 我们争取在2015 RTM 中实现STL常量表达式。现在,必要的类库修改和相关测试工作已基本就绪, 编译器团队正在有条不紊地修复一些编译器bug。尽管编译器仅限于C++11常量表达式, 但是已列入当前C++17工作报告的常量表达式,我们将会在STL中实现大部分。 (会有少数例外情况; 例如, 为了遍历所有元素,initializer_list 中的min ()/max()/minmax() 要求支持C++14 扩展常量表达式。)
[SFINAE] 编译器因需要支持SFINAE表达式而中断。
[VS 2013] VS 2013版本支持此特性。
[VS 2015] VS 2015 RC版本支持此特性。
[2015 opt-in] VS 2015 可选项版本支持此特性, 但由宏保护。默认情况下, 我们会提供auto_ptr等模板类。如果在项目工程中定义了 _HAS_AUTO_PTR_ETC 为0 (应该该通过命令行或项目文件来定义,而不是通过#define), 我们将不提供auto_ptr等模板类。
此可选择项在2015 RTM中保持不变。我计划在下一个重大版本中设计为opt-out, 在重大版本之后, 我打算完全取消auto_ptr等模板类。现在将是你整合代码的好机会。(我已经通知了Boost的维护者。)
[2015 RTM] VS 2015 RTM版本支持。
[N/A] 这些提议改变了标准说法, 但实际上并没有影响到实现者或者用户。出于完整性考虑,我把它们列为不支持。
CTP1之后,我们修复了大约一百多个STL 的bug- 包括彻底修改了头文件 <functional>。 在完成所有常量表达式之后,我会像往常一样写一篇较详细的更新博客。
常见问题
问:现在已是2015年,你为何还没有完成所有C++11新特性?
答:我们正在加快速度, 但不可能无限的加速。核心语言特性表格中已有31行在2015中变为是 (马上将变为32行-- C++11 常量表达式 即将全部实现) 。考虑到实际情况, 一些特性比较大 (如noexcept), 一些比较小(如 __func__), 还有一些交叉重复(如有一些重要bug需要在非静态数据成员初始值设定项和初始值设定项列表中修复), 这就是两年内的一大堆工作。实现其余特性将涉及到很多重要变动,只是我们不能勉强把它集成在RC发布版本中 (如,SFINAE表达式, C99 预处理器以及 C++98两项名称查找)。
问: 我需要SFINAE表达式。
答:这并不是一个问题! 但是说认真的, 我确实看到有人提议"SFINAE",很显然他们并不清楚自己提议的是什么。因此, 澄清如下问题:
如果你还不知道SFINAE 代表什么,说明你还不需要SFINAE 表达式。如果你知道它代表Substitution Failure Is Not An Elephant, 那么,你应该能察觉到传统SFINAE 和SFINAE表达式之间的区别。VS 支持传统C++98已至少有十年。为支持传统SFINAE,标准委员会最初的意图是使如类似(T, typename T::iterator)的重载能与其它重载友好共存, 即使模板参数能推导出T=int。(替代会产生"typename int::iterator",这显然会失败, 但随后标准委员会规定将重载从审议中删除, 允许考虑其它重载。) 后来, “邪恶“的开发者注意到,编译期常量可以控制重载的存在。这使C++11的 enable_if变的非常强大, enable_if<MyCondition, MyType>::type exists if 和only if MyCondition is true –—— 它可以是任意的编译期常量, 如 is_integral<T>::value.
尽管SFINA表达式功能非常强大, 但是传统的 SFINAE所用之处有限 , 如 ::type not existing. C++11中的SFINAE 表达式要求编译器在生成无效表达式后,能自动忽略掉模板重载, 如within decltype. (完整的规则更加复杂,这仅是一个汇总。) 这允许类库查询表达式是否有效,这是非常有用的。
VS还不支持SFINAE 表达式的原因是编译器还没有准备就绪。SFINAE表达式要求具有推测编译和完全回溯到附近错误表达式的能力。这对C1XX(C++编译器)来说非常困难,它还不能维护所有的抽象语法树。编译器开发团队正在改进代码库以支持SFINAE表达式,但这里还不支持。
问. 你什么时候实现SFINAE表达式?
答. 我们计划在2015 RTM 版本之后,立即在编译器上实现SFINAE 表达式, 同时我们还计划在2015 Update版本中集成该特性, 以支持产品使用。 (但并没有必要是2015 Update 1。这可能需要更长的时间。)
要特别清楚的是, 这项特性仅在编译器上支持, 不包含类库。C++11 标准类库中规定的SFINAE 表达式可用的地方很少, 而实际上我们已经实现了。(如is_assignable 和allocator_traits, 在这里,编译器采取了一些特殊方法来支持该特性。) C++14在至少两个地方增加了这一表达式,SFINAE表达式必须使用: std::function construction/assignment 和result_of。当编译器准备就绪后,我将修改STL,但是我并不打算将这些类库的改变集成在Update版本中. 我之所以修改STL头文件的原因是更新创建定义规则冲突的潜能,当对象文件和静态类库在不同版本如RTM/Update中编译时,它们的链接文件是一起的。我们将冒险修复一些在运行期的重要Bug, (最近大部分bug是std::string 内存泄漏,已在2010 SP1中修复), 但还没有实现C++14新特性,由此产生的编译器错误是可以避开的。
问:有关C99核心语言特性,或者C11核心语言特性及标准类库?
答:我们的首要任务是保持C++的一致性,之所以实现C99标准类库,是因为C++通过引用来合并C99标准。截止到当前的工作报告,C++还没有全部合并C99语言(只有上表列出的少数特性),这也不是永远没有可能。在未来,可能会将一部分并入C11标准类库,但这尚未实现。
在VS2013中,为了支持一些常见的类库,编译器开发团队在C模型中实现了一些C99核心语言特性(如:设置初始值设定项,请参考 MSDN的完整列表项)。
问:除了上表中标记在RTM中集成的特性,你还会在RC和RTM之间增加更多的新特性吗?
答:除了上表中所列:实现编译器的C11常量表达式和标准类库中的大部分常量表达式之外,几乎没有可能了。我们正在努力稳定已经实现了的新特性。
问:什么是Kiri-kin-也就是形而上学第一定律?
答. 凡是不真实的,根本就不存在。
Stephan T. Lavavej
高级开发工程师 - Visual C++类库团队