有一种新的 c + + 标准和新版本的 Visual c + +,新的版本Visual C++将更加符合C++标准!
在其发展过程中新的 c + + 标准被 (乐观) 称为 C + + 0x。它最后被发布在 2011 年,和现在称为 C + + 11。
对于 Visual c + +,它有三个不同版本的数字, 有不同的内部版本和编译器版本 (cl.exe 和_MSC_VER宏-显示这是不同因为我们 c + + 编译器早在 Visual c + + 中的"可视化")。例如:
VS 2005 == VC8 == _MSC_VER 1400
VS 2008 == VC9 == _MSC_VER 1500
VS 2010 == VC10 == _MSC_VER 1600
在内部,就只是 VC11。
如果读了C++0X标准,以及熟悉VC的诸个版本的不同,就会理解。
C++11 Core Language Features | VC10 | VC11 |
Rvalue references v0.1, v1.0, v2.0, v2.1, v3.0 | v2.0 | v2.1* |
ref-qualifiers | No | No |
Non-static data member initializers | No | No |
Variadic templates v0.9, v1.0 | No | No |
Initializer lists | No | No |
static_assert | Yes | Yes |
auto v0.9, v1.0 | v1.0 | v1.0 |
Trailing return types | Yes | Yes |
Lambdas v0.9, v1.0, v1.1 | v1.0 | v1.1 |
decltype v1.0, v1.1 | v1.0 | v1.1** |
Right angle brackets | Yes | Yes |
Default template arguments for function templates | No | No |
Expression SFINAE | No | No |
Alias templates | No | No |
Extern templates | Yes | Yes |
nullptr | Yes | Yes |
Strongly typed enums | Partial | Yes |
Forward declared enums | No | Yes |
Attributes | No | No |
constexpr | No | No |
Alignment | TR1 | Partial |
Delegating constructors | No | No |
Inheriting constructors | No | No |
Explicit conversion operators | No | No |
char16_t and char32_t | No | No |
Unicode string literals | No | No |
Raw string literals | No | No |
Universal character names in literals | No | No |
User-defined literals | No | No |
Standard-layout and trivial types | No | Yes |
Defaulted and deleted functions | No | No |
Extended friend declarations | Yes | Yes |
Extended sizeof | No | No |
Inline namespaces | No | No |
Unrestricted unions | No | No |
Local and unnamed types as template arguments | Yes | Yes |
Range-based for-loop | No | No |
override and final v0.8, v0.9, v1.0 | Partial | Partial |
Minimal GC support | Yes | Yes |
noexcept | No | No |
C++11 Core Language Features: Concurrency | VC10 | VC11 |
Reworded sequence points | N/A | N/A |
Atomics | No | Yes |
Strong compare and exchange | No | Yes |
Bidirectional fences | No | Yes |
Memory model | N/A | N/A |
Data-dependency ordering | No | Yes |
Data-dependency ordering: function annotation | No | No |
exception_ptr | Yes | Yes |
quick_exit and at_quick_exit | No | No |
Atomics in signal handlers | No | No |
Thread-local storage | Partial | Partial |
Magic statics | No | No |
C++11 Core Language Features: C99 | VC10 | VC11 |
__func__ | Partial | Partial |
C99 preprocessor | Partial | Partial |
long long | Yes | Yes |
Extended integer types | N/A | N/A |
这里是快速指南,希望大家有一定的C++基础,熟悉啥是 c + + 11:
Rvalue 引用:N1610"Rvalues 类对象的初始化的澄清"是早期尝试启用无 rvalue 引用 move 语意。
因为这些新规则还没有完全实现 VC11 开发者预览中,表说:"v2.1*"。这是正在跟踪的活动的 bug。
Rvalue 引用v3.0添加自动生成的构造函数和移动赋值运算符在一定条件下的新规则。这不会进行中 VC11,还将继续遵循的永远不会自动生成 move 构造函数/移动页本页的行为。
Lambda:Lambda 被选入工作文件 (v0.9) 和可变 lambda 添加 (v1.0) 后,标准化委员会彻底改革措辞,生产 lambda 1.1 版。这太晚发生才能实现页本页,但我们已经实现了它 VC11。Lambda v1.1 措辞澄清在像引用静态成员或嵌套的 lambda 角情况下该怎么办。这可以修复 bug 引发复杂的 lambda 的一群。此外,无国籍的 lambda 现已转换为 VC11 中的函数指针。这不是在 N2927 的措辞,但不管怎样,我数它作为 lambda v1.1 的一部分。这是跨国公司直接投资 5.1.2 [expr.prim.lambda]/6:"没有lambda 捕获 lambda 表达式的封闭类型有公共非虚拟非明确const转换函数具有相同的参数和返回类型,如封闭类型的函数调用操作符的函数指针。此转换函数返回的值应函数的地址调用时,已调用该封闭类型的函数调用操作符相同的效果。"
对齐方式:页本页既 VC11 执行核心语言关键字alignas/alignof从对齐方式提案的最终表决通过工作文件。页本页已从 TR1 aligned_storage。VC11 标准库添加 aligned_union 和std::align() 。
标准布局和琐碎的类型:至于可以说,从N2342 "POD 的重新 ; 用户可见的变化解决核心问题 568 (修订 5)"是添加了is_trivial和is_standard_layout到<type_traits>。(N2342 执行很多手术核心语言的措辞,但它只是让东西明确用户可能没有受到不管怎样,因此不需要进行任何编译器更改)。我们将这些类型的特征在页本页,但他们只是重复 is_pod,所以我打电话说"不"支持。在 VC11,他们被动力由编译器挂钩,它们应给出准确的答案。
扩展的友元声明:是基本上完成 (它甚至不发出警告"非标准扩展",与一些其他登上扩展此表中不同)。所以已经标记页本页和 VC11 都为"是"。
重写和决赛:经历了短暂而复杂的演变。最初 (v0.8) 有 [[覆盖]],[[隐藏]],和 [[base_check]] 属性。然后 (v0.9) 属性被淘汰,并替换为上下文关键字。最后 (v1.0),他们沦落到"最后"类和"重写"和"最后"功能上。这使得它登上的扩展,如 VC 已经支持此"重写"语法功能,具有语义合理地靠近 C + + 11 的。"最后"也是支持的但根据不同的拼写"密封"。这符合我的表中的"局部"支持。
最小的 GC 支持:事实证明, N2670只用户可见的变化不是操作标准库函数,我们已经在页本页中捡了一堆。
序列点的措辞:后盯着N2239的变化,取代 C + + 98/03 的"序列点"措辞与 C + + 11 的"序前"措辞 (这是更有用的而且更友好多线程处理),似乎是编译器或标准库实现做什么。所以我已经标记这为不适用。
原子,等:原子、强比较和交换、双向围栏,和数据依赖顺序指定标准库机械。
内存模型:N2429提出核心语言识别存在的多线程处理,但似乎什么也不做编译器执行 (至少一已经支持多线程)。所以在表中不适用。
扩展的整数类型:N1988本身说:"实施成本上的最后一点: 这个扩展在大多数编译器可能会导致没有变化。任何编译器,已没有整数类型除外规定的标准 (和一些版本的长长,其任务是通过 N1811 变化) 将可能已经符合。"另一项不适用功能 !
这包括核心语言。至于标准库中,我没有这样的功能,漂亮表,但我有好消息:
在 VC11,我们打算完全支持 C + + 11 标准库,但实施编译器功能可以自定义。(另外,VC11 不会完全实现 C99 标准库,已经通过引用纳入 C + + 11 标准库。注意页本页和 VC11 已经有<stdint.h>)。这里是我们不断的变化的非详尽列表:
新头文件:<atomic>、 <chrono>、 <condition_variable>、 <future>、 <mutex>、 <ratio>、 <scoped_allocator>和<thread>。
进驻:根据需要由 C + + 11,我们已经实现了emplace()/emplace_front()/emplace_back()/emplace_hint()/emplace_after()在所有容器的"任意"数字的参数 (见下文)。例如,矢量 <T>有"模板 < typename … …Args > 无效 emplace_back (Args & & … … args)"的直接构造任意数量的任意参数,完美转发从向量的背部 T 类型的元素。这可以更有效地比push_back(T&&)(页本页支持从 1 的参数,并不是特别有用的侵位)。
人造 variadics:我们开发了一种新的模拟 variadic 模板方案。以前在 VC9 SP1 和页本页,我们一再包括 subheaders 在定义不同的每一次,为了杜绝为 0、 1、 2、 3,等参数的重载的宏。(例如,<memory> 包含内部 subheader <xxshared>反复,为了杜绝make_shared <T> (args,args,args)。)在 VC11,subheaders 已经过去了。现在我们 variadic 模板本身定义为宏 (带有大量的反斜杠延续),然后将其展开主宏。此内部实现更改具有某些用户可见的影响。首先,代码是更容易维护,更易于使用 (添加 subheaders 相当多的工作),并略小于偶尔无法读取。这是什么让我们轻松实现 variadic 进驻,应该更容易在将来壁球 bug。第二,很难走进调试器的情况 (抱歉 !)。第三,对的 (piecewise_construct_t,元组 < … … Args1 > > < Args2 … … 的元组) 对构造函数有"有趣"的效果。这就要求 N ^2 重载 (如果我们支持多达 10 元,这意味着 121 重载,因为空元组计数在这里太)。最初,我们发现这 (滥发出这么多对元组重载,再加上所有的重载,这些重载进驻) 消耗了大量的内存在编译期间,所以作为一种解决方法,我们减少了无穷。在 VC9 SP1 和页本页,无限是 10 (即"variadic"模板支持具有包容性的 0 到 10 参数)。在 VC11 的开发者预览中,无限是默认情况下的 5。这得回页本页是什么我们编译器内存消耗。如果您需要更多的参数 (例如你有代码编译 VC9 SP1 或页本页使用 6 元),有一个推卸。您可以定义_VARIADIC_MAX 5 至 10 包容性 (默认为 5) 项目范围。增加它将使编译器会消耗更多的内存。
随机性:uniform_int_distribution现在是完全不带偏见,和我们已经实现了shuffle() , <algorithm>,它直接接受像mersenne_twister的均匀随机数发生器.
抗运算符重载的地址:C + + 98/03 禁止其地址的运算符重载的 STL 容器元素。这是像CComPtr类做些什么,所以像CAdapt的帮助器类都必须屏蔽 STL 从这种重载。页本页的发展过程中,所做的 STL 的更改同时大规模重写 (对于 rvalue 引用,除其他外),STL 重载地址的运算符在某些情况下甚至更多。
然后 C + + 11 改变其需求,使运算符重载的地址可以接受。(C + + 11 和页本页,提供帮助器函数std::addressof(),这是能够获得真实地址的运算符重载无论对象。)页本页发送之前,我们试图审核所有 STL 容器中的事件"和元素",代之以"std::addressof(elem)"这是适当的抗性。在 VC11,我们已经进一步发展。现在我们已经审计所有容器和所有的迭代器,所以重载其地址的运算符的类应该是整个 STL 可用。任何剩余的问题都应通过 Microsoft 连接向我们报告的错误。(可以想象,grepping 为"及元素"是相当难 !)还没审核算法,但偶然一瞥向我表示他们并不特别喜欢的元素的地址。
还将超越 C + + 11 的几种方式:
令人容易失误的迭代器:但不是允许所需的 C + + 11 标准,已实施避免易失误的迭代器,所形容的"最小化依赖项内泛型类的快和小程序" N2911和N2980 "易失误的迭代器分配和初始化,修订 1"。
文件系统:已经添加<filesystem>头TR2 的建议,如 recursive_directory_iterator。 来自 Boost.Filesystem V2。它后来演变成Boost.Filesystem V3,但这都不会实现的 VC11。
最后,在众多的错误修正,我们开展了主要的优化 !所有我们的容器 (一般说来) 现最佳小给予其当前的表示形式。这指容器对象本身,不其指向胆量。例如,矢量包含三个原始指针。页本页,向量 x 86 发布模式,是 16 个字节。在 VC11,它是 12 个字节,这是最佳小。如果您在程序中有 100,000 的载体 — — VC11 将为您节省 400000 个字节,这是一个大问题。降低的内存使用节省了时间和空间。
这被通过避免存储空分配器和比较器。(会激活这些优化的自定义分配器/比较器太,只要是无类型强定义。)
这里是所有 x86 和 x 64 的大小。(32 位 ARM 是相当于 x 86 为这些目的)。当然,这些表包括发布模式下,调试模式包含所消耗的时间和空间的检查机械。我有 VC9 SP1 中, _SECURE_SCL默认为 1,而对于 VC9 SP1 中的_SECURE_SCL手动设置为 0,最大速度为单独的列。默认为 0 (现名为_ITERATOR_DEBUG_LEVEL的_SECURE_SCL页本页和 VC11).
x86 Container Sizes (Bytes) | VC9 SP1 | VC9 SP1 SCL=0 |
VC10 | VC11 |
vector<int> | 24 | 16 | 16 | 12 |
array<int, 5> | 20 | 20 | 20 | 20 |
deque<int> | 32 | 32 | 24 | 20 |
forward_list<int> | N/A | N/A | 8 | 4 |
list<int> | 28 | 12 | 12 | 8 |
priority_queue<int> | 28 | 20 | 20 | 16 |
queue<int> | 32 | 32 | 24 | 20 |
stack<int> | 32 | 32 | 24 | 20 |
pair<int, int> | 8 | 8 | 8 | 8 |
tuple<int, int, int> | 16 | 16 | 16 | 12 |
map<int, int> | 32 | 12 | 16 | 8 |
multimap<int, int> | 32 | 12 | 16 | 8 |
set<int> | 32 | 12 | 16 | 8 |
multiset<int> | 32 | 12 | 16 | 8 |
hash_map<int, int> | 72 | 44 | 44 | 32 |
hash_multimap<int, int> | 72 | 44 | 44 | 32 |
hash_set<int> | 72 | 44 | 44 | 32 |
hash_multiset<int> | 72 | 44 | 44 | 32 |
unordered_map<int, int> | 72 | 44 | 44 | 32 |
unordered_multimap<int, int> | 72 | 44 | 44 | 32 |
unordered_set<int> | 72 | 44 | 44 | 32 |
unordered_multiset<int> | 72 | 44 | 44 | 32 |
string | 28 | 28 | 28 | 24 |
wstring | 28 | 28 | 28 | 24 |
x64 Container Sizes (Bytes) | VC9 SP1 | VC9 SP1 SCL=0 |
VC10 | VC11 |
vector<int> | 48 | 32 | 32 | 24 |
array<int, 5> | 20 | 20 | 20 | 20 |
deque<int> | 64 | 64 | 48 | 40 |
forward_list<int> | N/A | N/A | 16 | 8 |
list<int> | 56 | 24 | 24 | 16 |
priority_queue<int> | 56 | 40 | 40 | 32 |
queue<int> | 64 | 64 | 48 | 40 |
stack<int> | 64 | 64 | 48 | 40 |
pair<int, int> | 8 | 8 | 8 | 8 |
tuple<int, int, int> | 16 | 16 | 16 | 12 |
map<int, int> | 64 | 24 | 32 | 16 |
multimap<int, int> | 64 | 24 | 32 | 16 |
set<int> | 64 | 24 | 32 | 16 |
multiset<int> | 64 | 24 | 32 | 16 |
hash_map<int, int> | 144 | 88 | 88 | 64 |
hash_multimap<int, int> | 144 | 88 | 88 | 64 |
hash_set<int> | 144 | 88 | 88 | 64 |
hash_multiset<int> | 144 | 88 | 88 | 64 |
unordered_map<int, int> | 144 | 88 | 88 | 64 |
unordered_multimap<int, int> | 144 | 88 | 88 | 64 |
unordered_set<int> | 144 | 88 | 88 | 64 |
unordered_multiset<int> | 144 | 88 | 88 | 64 |
string | 40 | 40 | 40 | 32 |
wstring | 40 | 40 | 40 | 32 |