语法甜点11:非成员的begin和end
    在C++ 03中,标准容器都提供了begin和end成员函数,但对于普通数组,则只能使用不同的写法。比如:
1 vector<int> v;
2 int a[100];
3 sort(v.begin(), v.end());
4 sort(a, a+sizeof(a)/sizeof(a[0]));

为了统一语法,C++ 11提供了非成员的begin和end函数。用法如下:

1 sort(begin(v), end(v));
2 sort(begin(a), end(a));

语法甜点12:显式虚函数重载   
在引入C++ 11之前,基类和派生类中的虚函数很容易产生错误使用的情况。比如:
a、基类添加了一个虚函数,但该虚函数与派生类中的某个已有普通函数相同。
b、派生类添加了一个普通函数,但该函数与基类中的某个已有虚函数相同。
为了避免这些情况,在C++ 11中可以使用override来显式地表明需要进行虚函数重载。比如:

 1 class Base 2 {3     virtual void some_func(float);4 };5 6 class Derived : public Base7  {8     virtual void some_func(int) override;        // 将产生编译错误9    virtual void some_func(float) override;    // 正确
10 };

注意:为了保持向后兼容,此功能是选择性的。
C++ 11中还引入了final指示符,用于防止类或接口被继承。比如:
 1 class  Base1 final { };2 class Derived1 : public Base1 { };            // 将产生编译错误3 class Base24 {5     virtual void f() final;6 };7 class Derived2 : public Base28 {9     void f();                                             // 将产生编译错误
10 };

语法甜点13:强类型枚举

在C++ 03中,枚举类型不是类型安全的。枚举类型被视为整数,这使得两种不同的枚举类型之间可以进行比较。C++ 03唯一提供的安全机制就是一个整数或一个枚举型值不能隐式转换为另一个枚举型值。
在C++ 11中,引入了enum class来声明类型安全的枚举类型。比如:
enum class IColor1 { Red, Blue, Gree=100, Black };

IColor1不能隐式地转换为整数类型,也不能与整数类型比较大小。使用枚举名时,必须明确指定其所属范围,比如:必须使用IColor1::Red,而不能单独使用Red。

在C++ 11中,使用enum class和传统的enum时,还可以指定其所用的数据类型,不指定时默认为int。比如:
1 enum class IColor2 : unsigned int { Red, Blue, Gree=100, Black };
2 enum IColor3 : unsigned int { Red, Blue, Gree=100, Black };

另外,在C++ 03中,无法对枚举类型进行前置声明。而在C++ 11中,只要是使用了指定数据类型的新式枚举,都可以进行前置声明。比如:

1 enum class IColor1;
2 enum class IColor2 : unsigned int;
3 enum IColor3 : unsigned int;

语法甜点14:模板别名
在C++ 03中,可以使用typedef给模板类指定一个新的类型名称,但却不能给类模板指定别名。比如:
1 template< typename first, typename second, int third>
2 class SomeType;   template< typename second>
3 typedef SomeType<OtherType, second, 5> TypedefName;  // 在C++ 03中是不合法的

为了能够定义类模板的别名,C++ 11允许像下面这样使用using关键字:

1 template< typename first, typename second, int third>
2 class SomeType;
3 template< typename second>
4 using TypedefName = SomeType<OtherType, second, 5>;

另外,using也能定义一般类型的别名,此时等同于typedef。比如:

1 typedef void (*Func)(int);
2 using  Func = void (*)(int);

语法甜点15:无限制的union
在C++ 03中,并非任意的数据类型都能做为union的成员。比方说,带有non-trivial构造函数的类型就不能是 union 的成员。在C++ 11中,移除了所有对union的使用限制,除了其成员仍然不能是引用类型这种情况。 
 1 struct point2 {3      point() {}4      point(int x, int y): m_x(x), m_y(y) {}5      int m_x, m_y;6 };7 union8 {9      int z;
10      double w;
11      point p;                     // 在C++ 03中不合法;在C++ 11中合法
12 };

备注:C++ 03中不适合做union成员变量的情形有以下几种:

1、类或结构体中含有non-trival的构造函数(拷贝构造函数)、析构函数、拷贝赋值操作符、虚函数等。
2、类的基类和成员变量中含有1中所述几个函数。
3、静态变量。
4、变量引用。
语法甜点16:新的字符串字面值
C++ 03提供了两种字符串字面值。第一种,包含有双引号,产生以空字符结尾的const char数组。第二种,有着前标L,产生以空字符结尾的const wchar_t数组,其中wchar_t代表宽字符。C++ 03不支持Unicode编码。
在C++ 11中,为了加强C++编译器对Unicode的支持,类别char的定义被修改为其大小至少能够存储UTF-8的8位编码,并且能够容纳编译器的基本字符集的任何成员。
C++ 11 支持三种Unicode编码方式:UTF-8,UTF-16,和UTF-32。除了上述char定义的变更, C++ 11还增加了两种新的字符类别:char16_t和char32_t,用于存储UTF-16和UTF-32的字符。
下面展示了如何产生使用这些编码的字符串字面值:

1 u8"I'm a UTF-8 string."
2 u"This is a UTF-16 string."
3 U"This is a UTF-32 string."

第一个字符串的类型是通常的const char[],第二个字符串的类型是const char16_t[],第三个字符串的类型是const char32_t[]。 
为了避免在字符串中频繁使用转义字符的麻烦,C++11还提供了raw字符串字面值。比如:

1 R"(The String Data \ Stuff " )"
2 R"delimiter(The String Data \ Stuff " )delimiter"

raw字符串字面值能够和宽字面值或Unicode字面值结合起来使用,比如:

1 u8R"XXX(I'm a "raw UTF-8" string.)XXX"
2 uR"*@(This is a "raw UTF-16" string.)*@"
3 UR"(This is a "raw UTF-32" string.)"

语法甜点17:sizeof

在C++ 11中,允许sizeof运算符作用在类型的数据成员上,而无须明确的对象。在C++ 03中,这是不允许的,会导致编译错误。比如:

1 struct SomeType { OtherType member; };
2 sizeof(SomeType::member);        // 在C++ 03中不合法;在C++ 11中合法

语法甜点18:新的算法
C++ 11中新增了一些比较实用的算法。比如all_of、any_of、none_of、copy_n、copy_if和iota等。参考代码如下:

1 int a[5] = {-2, -1, 0, 1, 2};
2 auto funIsPositive = [](int v){return v>0;};
3 bool bRet = all_of(a, a+5, funIsPositive);             // false
4 bRet = any_of(a, a+5, funIsPositive);                  // true
5 bRet = none_of(a, a+5, funIsPositive);                // false
6 int b[5] = {0};
7 copy_n(a, 5, b);                                                // 将a开始的5个元素拷贝到b中
8 copy_if(a, a+5, b, funIsPositive);                        // 将1, 2两个数拷贝到b中
9 iota(a, a+5, 10);                                               // a中的每个元素加10

语法甜点19:泛化的常数表达式
C++ 03中本来就已经具有常数表示式的概念,比如:3+5,6*7等。常数表示式对编译器来说是优化的机会,编译器常在编译期运行它们并且将值存入程序中。同样地,在许多场合下,C++规范要求使用常数表示式。比如数组大小、枚举值等。
然而,常数表示式总是在遇到了函数调用时就终结。比如:

1 int GetFive() { return 5; }
2 int some_value[GetFive() + 5];         // 不合法

C++ 11引进关键字constexpr允许用户保证函数是编译期常数。比如:

1 constexpr int GetFive() { return 5; }
2 int some_value[GetFive() + 5];

语法甜点20:包装引用
包装引用类似于一般的引用。对于任意对象,我们可以通过模板类ref得到一个包装引用 (至于常引用,则可以通过 cref 得到)。考虑下面的代码:
1 void f (int &r)  { r++; }
2 template<class F, class P> void g (F f, P t)  { f(t); }
3
4 int n = 0 ;
5 g(f, n) ;
6 cout << n << endl;                     // 輸出0
7 g(f, ref(n));
8 cout << n << endl;                     // 輸出1

  语法甜点11:非成员的begin和end    在C++ 03中,标准容器都提供了begin和end成员函数,但对于普通数组,则只能使用不同的写法。比如:
1 vector<int> v;
2 int a[100];
3 sort(v.begin(), v.end());
4 sort(a, a+sizeof(a)/sizeof(a[0]));

为了统一语法,C++ 11提供了非成员的begin和end函数。用法如下:

1 sort(begin(v), end(v));
2 sort(begin(a), end(a));

语法甜点12:显式虚函数重载   
在引入C++ 11之前,基类和派生类中的虚函数很容易产生错误使用的情况。比如:
a、基类添加了一个虚函数,但该虚函数与派生类中的某个已有普通函数相同。
b、派生类添加了一个普通函数,但该函数与基类中的某个已有虚函数相同。
为了避免这些情况,在C++ 11中可以使用override来显式地表明需要进行虚函数重载。比如:

 1 class Base 2 {3     virtual void some_func(float);4 };5 6 class Derived : public Base7  {8     virtual void some_func(int) override;        // 将产生编译错误9    virtual void some_func(float) override;    // 正确
10 };

注意:为了保持向后兼容,此功能是选择性的。
C++ 11中还引入了final指示符,用于防止类或接口被继承。比如:
 1 class  Base1 final { };2 class Derived1 : public Base1 { };            // 将产生编译错误3 class Base24 {5     virtual void f() final;6 };7 class Derived2 : public Base28 {9     void f();                                             // 将产生编译错误
10 };

语法甜点13:强类型枚举

在C++ 03中,枚举类型不是类型安全的。枚举类型被视为整数,这使得两种不同的枚举类型之间可以进行比较。C++ 03唯一提供的安全机制就是一个整数或一个枚举型值不能隐式转换为另一个枚举型值。
在C++ 11中,引入了enum class来声明类型安全的枚举类型。比如:
enum class IColor1 { Red, Blue, Gree=100, Black };

IColor1不能隐式地转换为整数类型,也不能与整数类型比较大小。使用枚举名时,必须明确指定其所属范围,比如:必须使用IColor1::Red,而不能单独使用Red。

在C++ 11中,使用enum class和传统的enum时,还可以指定其所用的数据类型,不指定时默认为int。比如:
1 enum class IColor2 : unsigned int { Red, Blue, Gree=100, Black };
2 enum IColor3 : unsigned int { Red, Blue, Gree=100, Black };

另外,在C++ 03中,无法对枚举类型进行前置声明。而在C++ 11中,只要是使用了指定数据类型的新式枚举,都可以进行前置声明。比如:

1 enum class IColor1;
2 enum class IColor2 : unsigned int;
3 enum IColor3 : unsigned int;

语法甜点14:模板别名
在C++ 03中,可以使用typedef给模板类指定一个新的类型名称,但却不能给类模板指定别名。比如:
1 template< typename first, typename second, int third>
2 class SomeType;   template< typename second>
3 typedef SomeType<OtherType, second, 5> TypedefName;  // 在C++ 03中是不合法的

为了能够定义类模板的别名,C++ 11允许像下面这样使用using关键字:

1 template< typename first, typename second, int third>
2 class SomeType;
3 template< typename second>
4 using TypedefName = SomeType<OtherType, second, 5>;

另外,using也能定义一般类型的别名,此时等同于typedef。比如:

1 typedef void (*Func)(int);
2 using  Func = void (*)(int);

语法甜点15:无限制的union
在C++ 03中,并非任意的数据类型都能做为union的成员。比方说,带有non-trivial构造函数的类型就不能是 union 的成员。在C++ 11中,移除了所有对union的使用限制,除了其成员仍然不能是引用类型这种情况。 
 1 struct point2 {3      point() {}4      point(int x, int y): m_x(x), m_y(y) {}5      int m_x, m_y;6 };7 union8 {9      int z;
10      double w;
11      point p;                     // 在C++ 03中不合法;在C++ 11中合法
12 };

备注:C++ 03中不适合做union成员变量的情形有以下几种:

1、类或结构体中含有non-trival的构造函数(拷贝构造函数)、析构函数、拷贝赋值操作符、虚函数等。
2、类的基类和成员变量中含有1中所述几个函数。
3、静态变量。
4、变量引用。
语法甜点16:新的字符串字面值
C++ 03提供了两种字符串字面值。第一种,包含有双引号,产生以空字符结尾的const char数组。第二种,有着前标L,产生以空字符结尾的const wchar_t数组,其中wchar_t代表宽字符。C++ 03不支持Unicode编码。
在C++ 11中,为了加强C++编译器对Unicode的支持,类别char的定义被修改为其大小至少能够存储UTF-8的8位编码,并且能够容纳编译器的基本字符集的任何成员。
C++ 11 支持三种Unicode编码方式:UTF-8,UTF-16,和UTF-32。除了上述char定义的变更, C++ 11还增加了两种新的字符类别:char16_t和char32_t,用于存储UTF-16和UTF-32的字符。
下面展示了如何产生使用这些编码的字符串字面值:

1 u8"I'm a UTF-8 string."
2 u"This is a UTF-16 string."
3 U"This is a UTF-32 string."

第一个字符串的类型是通常的const char[],第二个字符串的类型是const char16_t[],第三个字符串的类型是const char32_t[]。 
为了避免在字符串中频繁使用转义字符的麻烦,C++11还提供了raw字符串字面值。比如:

1 R"(The String Data \ Stuff " )"
2 R"delimiter(The String Data \ Stuff " )delimiter"

raw字符串字面值能够和宽字面值或Unicode字面值结合起来使用,比如:

1 u8R"XXX(I'm a "raw UTF-8" string.)XXX"
2 uR"*@(This is a "raw UTF-16" string.)*@"
3 UR"(This is a "raw UTF-32" string.)"

语法甜点17:sizeof

在C++ 11中,允许sizeof运算符作用在类型的数据成员上,而无须明确的对象。在C++ 03中,这是不允许的,会导致编译错误。比如:

1 struct SomeType { OtherType member; };
2 sizeof(SomeType::member);        // 在C++ 03中不合法;在C++ 11中合法

语法甜点18:新的算法
C++ 11中新增了一些比较实用的算法。比如all_of、any_of、none_of、copy_n、copy_if和iota等。参考代码如下:

1 int a[5] = {-2, -1, 0, 1, 2};
2 auto funIsPositive = [](int v){return v>0;};
3 bool bRet = all_of(a, a+5, funIsPositive);             // false
4 bRet = any_of(a, a+5, funIsPositive);                  // true
5 bRet = none_of(a, a+5, funIsPositive);                // false
6 int b[5] = {0};
7 copy_n(a, 5, b);                                                // 将a开始的5个元素拷贝到b中
8 copy_if(a, a+5, b, funIsPositive);                        // 将1, 2两个数拷贝到b中
9 iota(a, a+5, 10);                                               // a中的每个元素加10

语法甜点19:泛化的常数表达式
C++ 03中本来就已经具有常数表示式的概念,比如:3+5,6*7等。常数表示式对编译器来说是优化的机会,编译器常在编译期运行它们并且将值存入程序中。同样地,在许多场合下,C++规范要求使用常数表示式。比如数组大小、枚举值等。
然而,常数表示式总是在遇到了函数调用时就终结。比如:

1 int GetFive() { return 5; }
2 int some_value[GetFive() + 5];         // 不合法

C++ 11引进关键字constexpr允许用户保证函数是编译期常数。比如:

1 constexpr int GetFive() { return 5; }
2 int some_value[GetFive() + 5];

语法甜点20:包装引用
包装引用类似于一般的引用。对于任意对象,我们可以通过模板类ref得到一个包装引用 (至于常引用,则可以通过 cref 得到)。考虑下面的代码:
1 void f (int &r)  { r++; }
2 template<class F, class P> void g (F f, P t)  { f(t); }
3
4 int n = 0 ;
5 g(f, n) ;
6 cout << n << endl;                     // 輸出0
7 g(f, ref(n));
8 cout << n << endl;                     // 輸出1

C++11语法甜点2相关推荐

  1. C++ 11语法甜点2

    转自:http://www.cnblogs.com/hujian/archive/2012/12/07/2807941.html 语法甜点11:非成员的begin和end 在C++ 03中,标准容器都 ...

  2. C++11主要新增使用语法介绍

    目录 1. C++11简介 2. 统一的列表初始化 2.1 {}初始化 2.2 std::initializer_list 3. 声明 3.1 auto 3.2 decltype 3.3 nullpt ...

  3. JavaScript核心语法总结

    1. 变量: ①先声明变量再赋值: var width; //var-用于声明变量的关键字 width = 5; //width-变量名 ②同时声明和赋值变量: var catName= " ...

  4. [C++11]常量表达式函数

    constexpr修饰函数. 普通函数/类成员函数. 1.函数必须要有返回值,并且return返回的表达式必须是常量表达式. 代码如下: #include <iostream> using ...

  5. 编译C++11/14方法

    Linux环境默认不支持C++11语法,通过下面方式编译 1.通过man g++可知,在g++编译选项后添加:-std=c++11即可 //编译C++11 # g++ test.cpp -std=c+ ...

  6. C++11更新内容(2)--完美转发--默认移动构造/移动赋值--1116

    1.完美转发 1.1万能引用 void Fun(int &x){ cout << "左值引用" << endl; } void Fun(const ...

  7. 【C++】-- C++11基础常用知识点(下)

    上篇: [C++]-- C++11基础常用知识点(上)_川入的博客-CSDN博客 目录 新的类功能 默认成员函数 可变参数模板 可变参数 可变参数模板 empalce lambda表达式 C++98中 ...

  8. C++ 11 内容总结

    核心语言的执行期表现强化 右值引用和move语义 在C++03及之前的标准,临时对象(称为右值"R-values",因为它们通常位于赋值运算子右侧)无法被改变,在C中亦同(且被视为 ...

  9. 基于C++11的muduo网络库

    文章目录 写在前面 项目编译问题 库安装的问题 项目测试代码 关于压力测试 项目概述 muduo网络库的reactor模型 muduo的设计 muduo各个类 辅助类 NonCopyable Time ...

最新文章

  1. 在C#中使用代理的方式触发事件
  2. Cisco实战——不让坏人登陆设备
  3. Windows Phone 7 Image Controller: Zoom In, Zoom Out, and Rotate (WP 7 图像控制器:放大,缩小,旋转)...
  4. pytorch实现简易分类模型
  5. MIN()与MAX()函数 的注意事项
  6. 第04篇 JDK版本导致Unsupported major.minor version 52.0 error
  7. google compute test Problem 1题
  8. 【转】PHP的Trait 特性
  9. CodeForces 757B Bash's Big Day(线性筛)
  10. 前端学习(2375):项目介绍结束
  11. c++ 协程_用yield实现协程
  12. NodeJS获取命令行后面的参数
  13. flask mysql环境配置_Flask教程4:数据库
  14. linux 分区顺序 boot,关于Liunx下的硬盘分区问题(/boot分区)?
  15. 第二节 数值、字符与字符串
  16. 程序员面试头条被拒,一年后逆袭拿到offer【巴分巴秒】
  17. DB2 数据库软件下载
  18. qq四国军旗2.1 beat03 builde018记牌器开发思路(四)
  19. 托业阅读时间怎么安排【zhasite】
  20. 10个国外免费下载电子书网站

热门文章

  1. 三相无刷电机驱动STC
  2. win10 电脑 连接 华为蓝牙耳机 (华为蓝牙耳机,win10搜索不到解决办法)
  3. Python 导入模块的四种方法(超详细)
  4. PyQt6 和 PyQt5 的差异
  5. java事务中使用try catch 导致事务不回滚的问题
  6. python 数组随机打乱
  7. Echarts 折线图 渐变色区域图 十字架
  8. Go语言如何实现可重入锁?
  9. java高级开发工程师面试,java面试简历系统
  10. 物联网研究框架与投资机会 附下载地址