VS2010、VS2012、VS2013对C++11的支持进度
来源:互联网 发布:淘宝英雄钢笔 编辑:程序博客网 时间:2024/05/21 21:47
原帖地址: http://msdn.microsoft.com/zh-cn/library/hh567368.aspx
对 C++11 功能的支持(现代 C++)
本文档描述了在 Visual C++ 中实现的 C++11 功能。 此信息是根据 Stephan T 发布的Visual C++ 团队博客进行改编的。 Lavavej.
本节内容
C++11 功能列表
核心语言功能表
核心语言功能表:并发
核心语言功能表:C99
功能表指南
右值引用
Lambdas
decltype
强类型/前向声明枚举
对齐
标准布局和普通类型
默认函数和已删除的函数
override 和 final
原子化及更多信息
标准库功能
C++11 功能列表
Visual Studio 2010 中的 Visual C++ 实现了 C++11 核心语言规范中的多种功能,并且 Visual Studio 2012 中的 Visual C++ 添加了更多 C++11 功能。 Visual Studio 2013 中的 Visual C++ 进一步扩展了此覆盖范围,并且还支持一些精选的 C++14 库功能。下表列出了 C++11 核心语言功能及其在 Visual Studio 2010、Visual Studio 2012 中的 Visual C++ 和 Visual Studio 2013 中的 Visual C++ 中的 Visual C++ 中的实现状态。
C++11 核心语言功能表
C++11 核心语言功能
Visual Studio 2010
Visual Studio 2012
Visual Studio 2013
右值引用 0.1 版、1.0 版、2.0 版、2.1 版、3.0 版
2.0 版
2.1* 版
2.1* 版
引用限定符
否
否
否
非静态数据成员初始值设定项
否
否
是
可变参数模板 0.9 版、1.0 版
否
否
是
初始值设定项列表
否
否
是
static_assert
是
是
是
auto 0.9 版、1.0 版
1.0 版
v1.0
1.0 版
尾部的返回类型
是
是
是
Lambdas 0.9 版、1.0 版、1.1 版
1.0 版
1.1 版
1.1 版
decltype 1.0 版、1.1 版
v1.0
1.1** 版
1.1 版
右尖括号
是
是
是
函数模板的默认模板参数
否
否
是
表达式 SFINAE
否
否
否
别名模板
否
否
是
Extern 模板
是
是
是
nullptr
是
是
是
强类型的枚举
Partial
是
是
前向声明枚举
否
是
是
特性
否
否
否
constexpr
否
否
否
对齐
TR1
Partial
Partial
委托构造函数
否
否
是
继承构造函数
否
否
否
显式转换运算符
否
否
是
char16_t/char32_t
否
否
否
Unicode 字符串文本
否
否
否
原始字符串文本
否
否
是
文本中的通用字符名
否
否
否
用户定义的文本
否
否
否
标准布局和普通类型
否
是
是
默认函数和已删除的函数
否
否
是*
扩展的友元声明
是
是
是
扩展的 sizeof
否
否
否
内联命名空间
否
否
否
无限制的联合
否
否
否
作为模板参数的本地和未命名类型
是
是
是
基于范围的 for 循环
否
是
是
override 和 final 0.8 版、0.9 版、1.0 版
Partial
是
是
最低 GC 支持
是
是
是
noexcept
否
否
否
[转到页首]
C++11 核心语言功能表:并发
C++11 核心语言功能:并发
Visual Studio 2010
Visual Studio 2012
Visual Studio 2013
改写的序列点
不可用
不可用
不可用
原子化
否
是
是
强比较和交换
否
是
是
双向界定
否
是
是
内存模型
不可用
不可用
不可用
数据依赖项排序
否
是
是
数据依赖项排序:函数批注
否
否
否
exception_ptr
是
是
是
quick_exit
否
否
否
信号处理程序中的原子化
否
否
否
线程本地存储
Partial
Partial
Partial
神奇的静态对象
否
否
否
[转到页首]
C++11 核心语言功能:C99
C++11 核心语言功能:C99
Visual Studio 2010
Visual Studio 2012
Visual Studio 2013
__func__
Partial
Partial
Partial
C99 预处理器
Partial
Partial
Partial
long long
是
是
是
扩展的整型
不可用
不可用
不可用
[转到页首]
功能表指南
右值引用
以下描述中使用的版本标识符(0.1 版、1.0 版、2.0 版、2.1 版、3.0 版)仅用来演示 C++11 的发展。标准本身不会使用它们。
N1610“通过右值澄清类对象的初始化”是早期在不引用右值的情况下支持移动语义的一种尝试。为方便讨论,我们称之为“右值引用 0.1 版”。它由“右值引用 1.0 版”取代。“右值引用 2.0 版”是 Visual Studio 2010 中的 Visual C++ 功能的基础,它禁止将右值引用绑定到左值,因此可以解决主要的安全性问题。“右值引用2.1 版”重新定义了此规则。让我们看一下vector<string>::push_back(),它具有重载 push_back(const string&) 和push_back(string&&) 以及调用 v.push_back("strval")。表达式"strval" 是字符串,并且是左值。(其他文本为右值,如整数 1729,但字符串有些特殊,因为它们是数组。)“右值引用 2.0 版”规则显示,string&& 无法绑定到"strval",因为 "strval" 是左值,因此 push_back(const string&) 是唯一可行的重载。这将创建一个临时 std::string,并将它复制到向量中,然后销毁效率不太高的临时std::string。 “右值引用 2.1 版”规则确认,将string&& 绑定到 "strval" 将创建临时 std::string,并且该临时字符串为右值。因此,push_back(const string&) 和push_back(string&&) 都是可行的,但首选 push_back(string&&)。将构造一个临时std::string,然后将它移至向量中。这样效率更高。
“右值引用 3.0 版”将添加新规则,以在特定条件下自动生成移动构造函数和移动赋值运算符。 但由于时间和资源限制,这未在 Visual Studio 2013 中的 Visual C++ 中实现。
[转到页首]
Lambdas
在 lambda 函数选入到工作文件(“0.9”版)并且已添加可变的 lambda(“1.0”版)之后,标准化委员会全面修订了措词。这产生了 lambda“1.1”版,这个版本现在已完全受支持。lambda 1.1 版的措词阐明了在特殊案例(例如引用静态成员或嵌套 lambda)中会发生的情况。这将修复由复杂 lambda 触发的问题。此外,无状态的 lambda 现在可转换为函数指针。这没有包含在 N2927 措词中,但是无论如何都会将它计作 lambda 1.1 版的一部分。C++115.1.2 [expr.prim.lambda]/6 具有以下说明:“无lambda-capture 的 lambda-expression 的闭包类型使用一个公共的非虚拟、非显式常量转换函数指向一个具有与闭包类型的函数调用运算符相同的参数和返回类型的函数。此转换函数返回的值应为一个函数的地址,调用该函数时,其效果和调用闭包类型的函数调用运算符相同。”(Visual Studio 2012 中的 Visual C++ 实现的效果甚至更好,因为它使无状态的 lambda 可转换为具有任意调用约定的函数指针。当你在使用期待像__stdcall 函数指针这类对象的 API 时,这点很重要。)
[转到页首]
decltype
在 decltype 选入到工作文件(1.0 版)后,在最后时刻收到了一个小的但很重要的修复(1.1 版)。这对从事 STL 和 Boost 工作的程序员很有好处。
[转到页首]
强类型/前向声明枚举
Visual Studio 2010 中的 Visual C++ 部分支持强类型的枚举(具体而言是,有关显式指定的基础类型的部分)。现在这些在 Visual Studio 中已完全实现,前向声明枚举的 C++11 语义也已完全实现。
[转到页首]
对齐
选入工作文件的对齐方式提案中的核心语言关键字alignas/alignof 未实现。Visual Studio 2010 中的 Visual C++ 具有来自 TR1 的aligned_storage。 Visual Studio 2012 中的 Visual C++ 已将aligned_union 和 std::align() 添加到标准库,而且重大的问题已在 Visual Studio 2013 中的 Visual C++ 中修复。
[转到页首]
标准布局和普通类型
来自 N2342“POD 重新访问;解决核心问题 568(修订 5)”的公开更改是将 is_trivial 和is_standard_layout 添加到标准模板库的 <type_traits>。(N2342 修改了大量核心语言措词,但无需进行编译器更改。)这些类型特征在 Visual Studio 2010 的 Visual C++ 中已提供,但它们只是复制了is_pod。 因此,本文档中之前的表显示“不支持”。它们现在由设计用于给出精确答案的编译器挂钩驱动。
STL 的 common_type<> 在 Visual Studio 2013 中的 Visual C++ 中得到了迫切需要的修复。common_type<> 的 C++11 规范导致意外后果;具体而言,它使common_type<int, int>::type 返回 int&&。因此,Visual Studio 2013 中的 Visual C++ 可实现建议用于库工作组问题 2141 的解决方法,使common_type<int, int>::type 返回 int。
作为此更改的副作用,标识用例不再起作用(common_type<T> 并不总是产生T 类型)。 这将遵循建议的解决方法,但其将中断依赖于先前行为的所有代码。
如果需要标识类型特征,请不要使用 <type_traits> 中定义的非标准std::identity,因为它对 <void> 无效。 相反,实现您自己的标识类型特征以满足您的需求。以下是一个示例:
template <typename T> struct Identity { typedef T type;};
有关其他重大更改,请参见 Visual C++ 中的重大更改。
[转到页首]
默认函数和已删除的函数
这些函数现在均受支持,但此种情况例外:对于默认函数,不支持使用 =default 请求识别成员的移动构造函数和移动赋值运算符。复制和移动操作并不按照标准规定的方式进行精确交互 - 例如,指定删除移动会同时禁止显示复制操作,但 Visual Studio 2013 中的 Visual C++ 不会。
有关如何使用默认函数和已删除的函数的信息,请参见 C++ 函数定义。
[转到页首]
override 和 final
这经历了短暂而复杂的发展。 最初,在0.8 版中,具有 [[override]]、[[hiding]] 和 [[base_check]] 特性。然后在0.9 版中,消除了这些特性并将其替换为上下文关键字。最后,在1.0 版中,将它们精简为类的“final”以及函数的“override”和“final”。这使它成为一个获得提升的扩展,因为 Visual Studio 2010 中的 Visual C++ 已支持对函数使用此“override”语法,并且语义相当接近于 C++11 中的语义。“final”也受支持,但拼写不同(“sealed”)。现在完全支持“override”和“final”的标准拼写和语义。有关更多信息,请参见override 说明符和final 说明符。
[转到页首]
原子化及更多信息
原子化、强比较和交换、双向界定和数据依赖项排序指定现在已实现的标准库机制。
相关 STL 标头: <atomic>、<chrono>、<condition_variable>、<future>、<mutex>、<ratio>、<scoped_allocator> 和 <thread>。
[转到页首]
标准库功能
这涵盖核心语言。 至于 C++11 标准库,我们虽没有漂亮的功能比较表,但 Visual Studio 2012 中的 Visual C++ 已实现此功能,但具有两个例外。首先,当某个库功能依赖于编译器中缺少的功能时,该功能要么是模拟的(例如,make_shared<T>() 的模拟可变参数模板),要么没有实现。(仅有少数情况现在已经在 Visual Studio 2013 中的 Visual C++ 中完全实现,其中最值得注意的是 <initializer_list>。)C99 已在 Visual Studio 2013 中的 Visual C++ 和提供的 C++ 包装器标头中实现,并且例外情况非常少。有关更多信息,请参阅 Visual Studio 2013 中的 C99 库支持。
下面列出了 Visual Studio 2012 中的 Visual C++ 和 Visual Studio 2013 中的 Visual C++ 中的部分更改:
定位:根据 C++11 的要求,emplace()/emplace_front()/emplace_back()/emplace_hint()/emplace_after() 已在所有包含“任意”数量参数的容器中实现(请参见“模拟的可变参数”部分)。例如,vector<T> 具有“template <typename... Args> void emplace_back(Args&&... args)”(它在向量的后面从任意数量的任意参数时直接构造元素类型 T,这称为“完全转发”)。这相对于push_back(T&&)(将涉及额外的移动构造和析构)效率更高。
可变参数:Visual Studio 2012 中的 Visual C++ 具有用于模拟可变参数模板的方案。在 Visual Studio 2013 中的 Visual C++ 中,取消了模拟,并完全实现了可变参数。如果你的代码依赖旧的模拟可变参数行为,则必须修复它。 但是,切换到实际可变参数模板增加了编译次数,并降低了编译器的内存消耗。
显式转换运算符:在核心语言中,显式转换运算符是一项常规功能 — 例如,你可以具有explicit operator MyClass()。 但是,标准库当前仅使用一种形式:explicit operator bool(),这使类成为安全的布尔值可测试的类。(无格式“operator bool()”是非常危险的。)过去,Visual C++ 模拟了带有operator pointer-to-member() 的 explicit operator bool(),这导致各种问题,并且效率有些低下。现在,完全移除了此“虚拟 bool”工作区。
随机性: uniform_int_distribution 现在是完全公平的,并且在 <algorithm> 中实现了shuffle(),这样便可以直接接受统一随机数生成器,如 mersenne_twister。
防止重载 address-of 运算符:C++98/03 禁止 STL 容器的元素重载其 address-of 运算符。这是类似CComPtr 的类完成的操作,因此使 STL 避免此类重载需要类似 CAdapt 的帮助程序类。开发 Visual Studio 2010 中的 Visual C++ 时,STL 更改使其在更多情况下拒绝重载 address-of 运算符。C++11 更改了相关要求,使得重载 address-of 运算符可接受。Visual Studio 2010 中的 C++11 和 Visual C++ 提供帮助程序函数std::addressof(),此函数可获取对象的真实地址(无论运算符是否重载)。在发布 Visual Studio 2010 中的 Visual C++ 之前,我们已尝试将“&elem”替换为具有一定抵抗性的“std::addressof(elem)”。Visual Studio 2012 中的 Visual C++ 更进一步,这样重载 address-of 运算符的类就能在整个 STL 中使用了。
Visual Studio 2012 中的 Visual C++ 在下列方面超出了 C++11 的范围:
SCARY 迭代器:实现了 SCARY 迭代器,如N2911“在泛型类中最小化依赖项以获得更快且更小的程序”和N2980“SCARY 迭代器分配和安装,第一版”中所述,这在 C++11 标准是允许的,但不是必需的。
文件系统:已添加 TR2 建议中的 <filesystem> 标头。 它提供recursive_directory_iterator 和其他有趣功能。在 TR2 的工作冻结之前,由于 C++0x 很晚才投入运行且将更改为 C++11,因此从Boost.Filesystem V2 派生出了 2006 协议。它稍后将演变为 Boost.Filesystem V3,但未在 Visual Studio 2012 中的 Visual C++ 中实现。
一个主要优化!现在,我们的所有容器相对于当前的表示形式都具有最小的合适大小。这指的是容器对象本身,而不是它们指向的内容。例如,std::vector 包含三个原始指针。在 Visual Studio 2010 中的 Visual C++ 中,x86 发布模式std::vector 为 16 字节。在 Visual Studio 2012 中的 Visual C++ 中,它为 12 字节,这是最小的合适大小。如果你的程序有 100,000 个向量,则 Visual Studio 2012 中的 Visual C++ 将为你节省 400,000 字节,这很了不起。减少内存使用率可节省空间和时间。
这是通过避免存储空的分配器和比较运算符来实现的,因为 std::allocator 和 std::less 是无状态的。(只要自定义分配器/比较运算符是无状态的,也会为它们启用这些优化。显然,无法避免有状态的分配器/比较运算符的存储,但这种情况极为少见。)
Visual Studio 2013 中的 Visual C++ 超越了 C++11 来实现一些关键的 C++14 库功能:
“透明运算符函子”less<>、greater<>、plus<>、multiplies<> 等。
make_unique<T>(args...) 和 make_unique<T[]>(n)
cbegin()/cend()、rbegin()/rend() 和crbegin()/crend() 非成员函数。
[转到页首]
请参见
参考
概念
其他资源
- VS2010、VS2012、VS2013对C++11的支持进度
- VS2010、VS2012、VS2013、VS2015对C++11的支持进度
- VS2010、VS2012、VS2013对C++11的支持进度
- 使用VS2010打开VS2012/VS2013 的解决方案
- vs2010打开vs2012,vs2013编写的工程。
- vs2010打开vs2012,vs2013编写的工程
- 解决VS2010、VS2012、VS2013工程目录过大的问题
- MFC vs2008,vs2010,vs2012,vs2013启动页的实现
- Visual Studio 的生成事件 (vs2010,vs2012,vs2013,vs2015)
- VS2010对C++11的支持程度
- 【C++】 VS2010 打开VS2012 新建的工程
- C#-vs2010打开vs2013的解决方案
- Vs2013(VS2012,vs2011,vs2010)+opencv2.4.8配置
- 从网上找的 visual studio 的各个版本下载地址,vs2010/vs2012/vs2013带注册码
- C# Tips: 将 VS2012 / VS2013 的.sln文件、project文件转换成 VS2010格式
- vs2013 EF+MYSQL vs2012 EF+MYSQL vs2010 EF+MYSQL 选择数据源时遇到的问题
- win7安装vs2010、vs2012、vs2013出现 DDSet_Error: Internal error: 1058或1060的解决方法
- win8安装vs2010、vs2012、vs2013出现 DDSet_Error: Internal error: 1058或1060的解决方法
- CocoaPods安装和使用教程
- Spring jdbc 的使用
- linux命令 -- touch 命令
- Cocos2d-x 多分辨率适配完全解析
- LNK1123: 转换到 COFF 期间失败: 文件无效或损坏
- VS2010、VS2012、VS2013对C++11的支持进度
- 斐波那契线性递归
- Jackson 高性能的JSON处理 ObjectMapper
- springmvc获取HttpServletRequest对象
- 关于iOS测试机个数上限的详细规则
- java Swing框架应用,计算器的设计实现
- 1.数据结构的定义
- 出现java.lang.UnsupportedClassVersionError 错误的原因
- Linux diff与patch的深入分析