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特性。)

核心语言

C++11 核心语言特性

VS 2013

VS 2015

备注

Rvalue references

部分

 

ref-qualifiers

 

Non-static data member initializers

部分

[RC]

Variadic templates

 

Initializer lists

部分

[RC]

static_assert

 

auto

 

Trailing return types

 

Lambdas

 

decltype

 

Right angle brackets

 

Default template args for function templates

 

Expression SFINAE

 

Alias templates

 

Extern templates

 

nullptr

 

Strongly typed enums

 

Forward declared enums

 

Attributes

[RTM]

constexpr

部分

[1]

Alignment

部分

 

Delegating constructors

 

Inheriting constructors

 

Explicit conversion operators

 

char16_t and char32_t

 

Unicode string literals

 

Raw string literals

 

Universal character names in literals

[RC]

User-defined literals

 

Standard-layout and trivial types

 

Defaulted and deleted functions

部分

 

Extended friend declarations

 

Extended sizeof

 

Inline namespaces

 

Unrestricted unions

 

Local and unnamed types as template args

 

Range-based for-loop

 

override and final

 

Minimal GC support

 

否except

 

C++11 核心语言特性: 并行

VS 2013

VS 2015

备注

Reworded sequence points

 

Atomics

 

Strong compare and exchange

 

Bidirectional fences

 

Memory model

 

Data-dependency ordering

 

Data-dependency ordering: attributes

[RTM]

exception_ptr

 

quick_exit and at_quick_exit

 

Atomics in signal handlers

[2]

Thread-local storage

部分

 

Magic statics

 

C++11 核心语言特性: C99

VS 2013

VS 2015

备注

__func__

部分

 

C99 preprocessor

部分

部分

[3]

long long

 

Extended integer types

N/A

N/A

[4]

C++14 核心语言特性

VS 2013

VS 2015

备注

Tweaked wording for contextual conversions

 

Binary literals

 

auto and decltype(auto) return types

 

init-captures

 

Generic lambdas

 

Variable templates

 

Extended constexpr

 

NSDMIs for aggregates

 

Avoiding/fusing allocations

N/A

N/A

[5]

[[deprecated]] attributes

[RTM]

Sized deallocation

[RC]

Digit separators

[RC]

C++1z (C++17?) 核心语言特性

VS 2013

VS 2015

备注

New rules for auto with braced-init-lists

[RC]

Terse static_assert

 

typename in template template-parameters

[RC]

Removing trigraphs

 

Nested namespace definitions

 

Fixing qualification conversions

 

Attributes for namespaces and enumerators

[RTM]

u8 character literals

 

Allowing more 否n-type template args

 

Fold expressions

 

备注: 

[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

N3302

constexpr For <complex>

constexpr

C++14

N3469

constexpr For < chrono>

constexpr

C++14

N3470

constexpr For <array>

constexpr

C++14

N3471

constexpr For <initializer_list>, <tuple>, <utility>

constexpr

C++14

N3545

integral_constant::operator()()

constexpr

C++14

N3669

Fixing constexpr Member Functions Without const

constexpr

C++14

N3789

constexpr For <functional>

SFINAE

C++14

N3462

SFINAE-Friendly result_of

VS 2015

C++14

N3642

UDLs For < chrono>, <string> (1729ms, "meow"s, etc.)

VS 2015

C++14

N3644

Null Forward Iterators

VS 2015

C++14

N3654

quoted()

VS 2015

C++14

N3657

Heterogeneous Associative Lookup

VS 2015

C++14

N3658

integer_sequence

2015 RTM

C++14

N3659

<shared_mutex>

VS 2015

C++14

N3668

exchange()

VS 2015

C++14

N3670

get<T>()

VS 2015

C++14

N3671

Dual-Range equal(), is_permutation(), mismatch()

VS 2015

C++14

N3778

Sized Deallocation

VS 2015

C++14

N3779

UDLs For <complex> (3.14i, etc.)

VS 2015

C++14

N3887

tuple_element_t

2015 RTM

C++14

N3891

Renaming shared_mutex To shared_timed_mutex

VS 2015

C++17

N3911

void_t

2015 RTM

C++17

N4089

Safe Conversions In unique_ptr<T[]>

VS 2015

C++17

N4169

invoke()

2015 opt-in

C++17

N4190

Removing auto_ptr, random_shuffle(), And Old <functional> Stuff

VS 2015

C++17

N4258

noexceptCleanups

VS 2015

C++17

N4259

uncaught_exceptions()

VS 2015

C++17

N4277

Trivially Copyable reference_wrapper

VS 2015

C++17

N4279

insert_or_assign()/try_emplace() For map/unordered_map

VS 2015

C++17

N4280

size(), empty(), data()

VS 2013

C++14

N3346

Minimal Container Element Requirements

VS 2013

C++14

N3421

Transparent Operator Functors (less<>, etc.)

VS 2013

C++14

N3655

Alias Templates For <type_traits> (decay_t, etc.)

VS 2013

C++14

N3656

make_unique()

N/A

C++14

N3924

Discouraging rand()

N/A

C++17

N4284

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++类库团队

stl@microsoft.com