语法甜点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. 收好这份 Git 命令应急手册,关键时刻可保你一命
  2. BZOJ 1666 USACO 2006 Oct. 奶牛的数字游戏
  3. 娱乐化手游营销模式探索
  4. hdu 1863(最小生成树kruskal)
  5. mysql 优化 案例_[MySQL优化案例]系列 -- OPTIMIZE的威力
  6. 95-40-050-java.util.concurrent-CopyOnWriteArraySet
  7. d - 数据结构实验之查找四:二分查找_数据结构与算法笔记
  8. php jpeg不支持,php jpeg不支持怎么办
  9. 纪念一下挖到CSDN官网漏洞
  10. 小程序应用 饿了么美团外卖cps领券返利小程序+前端(带三级分销裂变)
  11. openid是什么意思?token是什么意思?
  12. 苹果App Store引发的悲喜狂欢
  13. 背单词的小智 (二分)
  14. 对接支付宝网站支付接口出现订单信息无法识别,请联系卖家的错误
  15. Reason Studios Reason 12 v12.2.5 WiN 音乐制作软件和机架插件
  16. IDM产品安全机制说明
  17. (转)一个大牛的acm历程(看着就要颤抖)
  18. VC中调用cmd命令的四种方式
  19. sendToTarget与sendMessage
  20. .trash-1000文件夹的疑问

热门文章

  1. 5月6阴阳师服务器维护,阴阳师5月6日维护更新公告 御魂加成开放购买
  2. 什么是正能量?怎样做一位正能量的人?
  3. 邮件安全风险高发,公安部、工信部、国家保密局联发预警
  4. 无线鼠标装不上驱动的问题
  5. JAVA Web项目开发SSM框架搭建(第一天)
  6. freeswitch之sofia模块
  7. a22_scala 伴生对象 伴生类
  8. 编译方舟编译器源码教程
  9. 跳转到第三方软件的方法
  10. MSP430F248TPMR 德州TI 超低功耗微控制器 封装LQFP