《Visual C++ 2012 开发权威指南》——第2章 Visual C++2012语言新特性2.1 Visual C++2012的语言新特性(1)

简介:

本节书摘来自异步社区出版社《Visual C++ 2012 开发权威指南》一书中的第2章,第2.1节,作者: 尹成 , 朱景尧 , 孙明龙 , 胡耀文,更多章节内容可以访问云栖社区“异步社区”公众号查看。

第2章 Visual C++2012语言新特性

Visual C++ 2012 开发权威指南
有一种新的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的诸个版本的不同,就会理解。

2.1 Visual C++2012的语言新特性(1)

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转换函数具有相同的参数和返回类型,如封闭类型的函数调用操作符的函数指针。此转换函数返回的值应函数的地址调用时,已调用该封闭类型的函数调用操作符相同的效果。”

lambda表达式隐式定义并构造未命名函数对象。lambda提供了一种轻型自然语法来定义使用lambda的函数对象,而不产生性能开销。

函数对象是自定义标准模板库(STL)算法行为的非常强大的方式,可以封装代码和数据(与普通函数不同)。但定义函数对象不太方便,因为需要编写完整的类。此外,它们不是在要用到它们的源代码中定义的,这种非局部性增加了这些对象的使用难度。库已尝试缓解一些复杂性和非局部性问题,但帮助不大,因为语法有点复杂而且编译器错误不是很友好。使用库中的函数对象也会降低效率,因为定义为数据成员的函数对象不是内联对象。

lambda表达式解决了这些问题。下面的代码段显示了一个lambda表达式,该表达式在程序中用于从整数向量中删除变量x和y之间的整数。

v.erase(remove_if(v.begin(),
  v.end(), [x, y](int n) { 
  return x < n && n < y; }),
  v.end());```
第二行显示了该lambda表达式。方括号(称为lambda引导)指示lambda表达式的定义。此lambda采用整数n为参数,lambda生成的函数对象具有数据成员x和y。若与一个等效的手写函数对象进行比较,可看到lambda的方便性和省时性:

class LambdaFunctor {
public:
 LambdaFunctor(int a, int b) : m_a(a), m_b(b) { }
 bool operator()(int n) const {
  return m_a < n && n < m_b; }
private:
 int m_a;
 int m_b;
};
v.erase(remove_if(v.begin(), v.end(),
 LambdaFunctor(x, y)), v.end());`
C++的新标准C++0x虽然还没有正式发布,但是已经进入了feature freeze的阶段,很多人都在猜测C++0x中的x到底是9还是10,从目前的情况来看,9是最大的可能了。Visual Studio 2012作为下一代开发工具,当然不会错过对新的C++标准C++0x的支持。除了随着之前发布的Visual C++Feature Pack而引入的TR1包含的部分特性外,在新的Visual Studio 2012中,还引入了4个重要的C++新特性。号称C++0x的“四大天王”。这些新特性的引入,必将给C++注入新的活力。

很多编程语言都支持匿名函数(anonymous function)。所谓匿名函数,就是这个函数只有函数体,而没有函数名。Lambda表达式就是实现匿名函数的一种编程技巧,它为编写匿名函数提供了简明的函数式的句法。

Lambda表达式使得函数可以在使用的地方定义,并且可以在Lambda函数中使用Lambda函数之外的数据。这就为针对集合操作带来了很大的便利。在作用上,Lambda表达式类似于函数指针和函数对象,Lambda表达式很好地兼顾了函数指针和函数对象的优点,却没有它们的缺点。相对于函数指针或是函数对象复杂的语法形式,Lambda表达式使用非常简单的语法就可以实现同样的功能,降低了Lambda表达式的学习难度,避免了使用复杂的函数对象或是函数指针所带来的错误。我们可以看一个实际的例子:

// LambdaDemo.cpp : 为控制台程序定义入口
//

#include"stdafx.h"
#include<algorithm>
#include<iostream>
#include<ostream>
#include<vector>

using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
  vector<int> 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<< " even";
    }else {
      cout<< " odd";
    }
  });
  cout<< endl;

  return 0;
}```
这段代码循环遍历输出vector中的每一个数,并判断这个数是奇数还是偶数。我们可以随时修改Lambda表达式而改变这个匿名函数的实现,修改对集合的操作。在这段代码中,C++使用一对中括号“[]”来表示Lambda表达式的开始,其后的“(int n)”表示Lambda表达式的参数。这些参数将在Lambda表达式中使用到。为了体会Lambda表达式的简洁,我们来看看同样的功能,如何使用函数对象实现:

include"stdafx.h"

include

include

include

include

using namespace std;

struct LambdaFunctor {
  void operator()(int n)const {
    cout<< n<< " ";
    if (n %2 == 0) {
      cout<< " even";
    }else {
      cout<< " odd";
    }

  }
};

int _tmain(int argc, _TCHAR* argv[])
{
  vector v;

  for (int i= 0; i< 10;++i) {
    v.push_back(i);
  }

  for_each(v.begin(), v.end(), LambdaFunctor());
  cout<< endl;

  return 0;
}`
通过比较我们就可以发现,Lambda表达式的语法更加简洁,使用起来更加简单高效。

相关文章
|
2月前
|
编译器 程序员 定位技术
C++ 20新特性之Concepts
在C++ 20之前,我们在编写泛型代码时,模板参数的约束往往通过复杂的SFINAE(Substitution Failure Is Not An Error)策略或繁琐的Traits类来实现。这不仅难以阅读,也非常容易出错,导致很多程序员在提及泛型编程时,总是心有余悸、脊背发凉。 在没有引入Concepts之前,我们只能依靠经验和技巧来解读编译器给出的错误信息,很容易陷入“类型迷路”。这就好比在没有GPS导航的年代,我们依靠复杂的地图和模糊的方向指示去一个陌生的地点,很容易迷路。而Concepts的引入,就像是给C++的模板系统安装了一个GPS导航仪
132 59
|
1月前
|
安全 编译器 C++
【C++11】新特性
`C++11`是2011年发布的`C++`重要版本,引入了约140个新特性和600个缺陷修复。其中,列表初始化(List Initialization)提供了一种更统一、更灵活和更安全的初始化方式,支持内置类型和满足特定条件的自定义类型。此外,`C++11`还引入了`auto`关键字用于自动类型推导,简化了复杂类型的声明,提高了代码的可读性和可维护性。`decltype`则用于根据表达式推导类型,增强了编译时类型检查的能力,特别适用于模板和泛型编程。
24 2
WK
|
1月前
|
机器学习/深度学习 人工智能 算法
那C++适合开发哪些项目
C++ 是一种功能强大、应用广泛的编程语言,适合开发多种类型的项目。它在游戏开发、操作系统、嵌入式系统、科学计算、金融、图形图像处理、数据库管理、网络通信、人工智能、虚拟现实、航空航天等领域都有广泛应用。C++ 以其高性能、内存管理和跨平台兼容性等优势,成为众多开发者的选择。
WK
80 1
|
2月前
|
算法 C++
2022年第十三届蓝桥杯大赛C/C++语言B组省赛题解
2022年第十三届蓝桥杯大赛C/C++语言B组省赛题解
52 5
|
2月前
|
Rust 资源调度 安全
为什么使用 Rust over C++ 进行 IoT 解决方案开发
为什么使用 Rust over C++ 进行 IoT 解决方案开发
91 7
WK
|
1月前
|
开发框架 移动开发 Java
C++和Java哪个更适合开发移动应用
本文对比了C++和Java在移动应用开发中的优劣,从市场需求、学习难度、开发效率、跨平台性和应用领域等方面进行了详细分析。Java在Android开发中占据优势,而C++则适合对性能要求较高的场景。选择应根据具体需求和个人偏好综合考虑。
WK
60 0
WK
|
1月前
|
安全 Java 编译器
C++和Java哪个更适合开发web网站
在Web开发领域,C++和Java各具优势。C++以其高性能、低级控制和跨平台性著称,适用于需要高吞吐量和低延迟的场景,如实时交易系统和在线游戏服务器。Java则凭借其跨平台性、丰富的生态系统和强大的安全性,广泛应用于企业级Web开发,如企业管理系统和电子商务平台。选择时需根据项目需求和技术储备综合考虑。
WK
93 0
|
2月前
|
C++
C++ 20新特性之结构化绑定
在C++ 20出现之前,当我们需要访问一个结构体或类的多个成员时,通常使用.或->操作符。对于复杂的数据结构,这种访问方式往往会显得冗长,也难以理解。C++ 20中引入的结构化绑定允许我们直接从一个聚合类型(比如:tuple、struct、class等)中提取出多个成员,并为它们分别命名。这一特性大大简化了对复杂数据结构的访问方式,使代码更加清晰、易读。
43 0
|
2月前
|
NoSQL API Redis
如何使用 C++ 开发 Redis 模块
如何使用 C++ 开发 Redis 模块
|
2月前
|
存储 编译器 C语言
深入计算机语言之C++:类与对象(上)
深入计算机语言之C++:类与对象(上)