Visual Studio 2010中C++的四大变化
微软将于2010年4月12日发布Visual Studio 2010正式版,对C++语言进行了修改,使其更加符合C++标准。本文将介绍对 C++ 语言的修改。我们来做一些分析。
在微软即将推出的Visual Studio 2010正式版中,它对C++语言做了一些改变。此前,51cto也报道过Visual Studio 2010中C++项目的升级问题。文章重点介绍了C++语言的一些变化。
拉姆达表达式
许多编程语言都支持匿名函数。所谓匿名函数,是指这个函数只有函数体而没有函数名。 Lambda 表达式是一种用于实现匿名函数的编程技术。它为编写匿名函数提供了简洁的函数语法。两者都是Visual Studio中的开发语言。 Visual Basic 和 Visual C# 很早就实现了对 Lambda 表达式的支持。最后,Visual C++ 这次也不甘落后,在 Visual Studio 2010 中添加了对 Lambda 表达式的支持。
Lambda 表达式允许在使用函数的地方定义函数,并且可以在 Lambda 函数中使用 Lambda 函数外部的数据。这给设置操作带来了极大的方便。从功能上来说,Lambda表达式类似于函数指针和函数对象。 Lambda 表达式考虑了函数指针和函数对象的优点,而没有缺点。与函数指针或函数对象复杂的语法相比,Lambda表达式可以用非常简单的语法实现相同的功能,降低了Lambda表达式的学习难度,避免了使用复杂的函数对象或函数指针带来的问题。出现错误。我们可以看一个实际的例子:
#include "stdafx.h" #include #include #include #include 使用命名空间 std; int _tmain(int argc, _TCHAR* argv[]) { 向量 v; for (int i = 0; i < 10; ++i) { v.push_back(i); } for_each(v.begin(), v.end(), [] (int n) { cout << n; if (n % 2 == 0) { cout << “偶数”; } else { cout << “ 奇怪的 ”; } }); cout << endl;返回 0; } #include "stdafx.h" #include #include #include #include 使用命名空间 std; int _tmain(int argc, _TCHAR* argv[]) { 向量 v; for (int i = 0; i < 10; ++i) { v.push_back(i); } for_each(v.begin(), v.end(), [] (int n) { cout << n; if (n % 2 == 0) { cout << “偶数 ”; } else { cout << “ 奇怪的 ”; } }); cout << endl;返回 0; }
修改be代码循环遍历输出向量中的每一个数,并判断这个数是奇数还是偶数。我们可以随意Lambda表达式而改变这个匿名函数的实现,修改集合的操作。在be代码中,C++使用范例中的“[]”来表示 Lambda 表达式的开始,其后面的“(int n)”表示 Lambda 表达式的参数。这些参数将在 Lambda 表达式中使用到。为了体会 Lambda 表达式的简单性,我们来看看如何使用函数对象实现相同的功能:
#include "stdafx.h" #include #include #include #include 使用命名空间 std; struct LambdaFunctor { void operator()(int n) const { cout << n << " "; if (n % 2 == 0) { cout << "偶数"; } else { cout << "奇数"; } } }; int _tmain(int argc, _TCHAR* argv[]) { 矢量 v; for (int i = 0; i < 10; ++i) { v.push_back(i); for_each(v.begin(), v.end(), LambdaFunctor()); cout << endl ;返回0; #include "stdafx.h" #include #include #include #include 使用命名空间 std; struct LambdaFunctor { void operator()(int n) const { cout << n << " "; if (n % 2 == 0) { cout << "偶数"; } else { cout << "奇数"; } } }; int _tmain(int argc, _TCHAR* argv[] ) { 向量 v; for (int i = 0; i < 10; ++i) { v.push_back(i); for_each(v.begin(), v.end(), LambdaFunctor()) ; cout << endl;返回0; }
通过比较我们可以发现 Lambda表达式语法更加简洁,使用#p#更加简单高效
静态断言static_assert
在之前的C++标准C++03中,我们可以使用两种断言:
◆在预处理中使用条件编译和#error指令,可以在预处理阶段检查一些编译条件。
◆可以使用宏assert进行运行时检查,保证程序逻辑的正确性。
但使用#error方法非常麻烦,而且无法检查模板参数,因为模板实例化是在编译时进行的,而#error方法是在预处理阶段进行的。断言宏在运行时检查。很容易看出,我们缺少的一件事是可用于在编译时进行检查的工具。于是,静态断言应运而生。
在新的C++标准C++0x中,增加了对静态断言的支持,并引入了新的关键字static_assert来表示静态断言。使用静态断言,我们可以在程序编译时检查某些条件是否成立。在调试模板函数的模板参数时,此功能特别有用。在编译期间,模板函数被实例化。这时,我们可以使用静态断言来测试模板函数的参数是否根据我们的设计有合适的值。例如,以下代码:
template struct Kitten { static_assert(N < 2, "Kitten 需要 N < 2."); }; int main() { Kitten<1> 薄荷; Kitten<3> jazz; return 0; } template struct Kitten { static_assert(N < 2, "Kitten 需要 N < 2."); }; int main() { Kitten<1> 薄荷;小猫<3>爵士乐;返回0;}
当我们在main函数中使用“1”实例化Kitten结构时,编译时静态断言static_assert会测试参数N的值,当N的值小于2时,会产生断言错误,相应的调试帮助信息输出到“错误列表”窗口,以便程序员能够快速定位问题,更方便地解决问题。
此外,静态断言还带来许多其他优点。例如,静态断言在编译时进行处理,不会造成任何运行时空间和时间开销,这使得它比断言宏更加高效。另一个重要的特性是,如果断言失败,它会生成有意义且足够的诊断信息,帮助程序员快速解决问题。自动关键字
在 C++ 中,auto 关键字的含义发生了变化。从 Visual Studio 2010 开始,auto 关键字将用于指示编译器根据变量的初始值确定变量的数据类型。换句话说,我们可以将 auto 视为一种新的数据类型,它可以“从初始化器(初始化)派生出它所代表的变量的真实类型”。 auto 关键字的使用可以极大地消除当前替代方案产生的冗长且容易出错的代码。我们看一个实际的例子:
#include #include