自己一直用的是C++98规范来编程,对于C++11只闻其名却没用过其特性。近期因为工作的需要,需要掌握C++11的一些特性,所以查阅了一些C++11资料。因为自己有C++98的基础,所以从C++98过渡到C++11并不算特别吃力,读了一些书籍后,算是对C++11有了个比较基础的理解,感觉程序员还是要经常保持新语言新特性的更新,现在 C++ 标准都出到C++17了!这篇文章就是对C++11一些常用新特性的一些总结,以C++98和 C++11在语法上的差异来突出C++11新特性的非凡优势。
一、新语法
1.自动类型推导auto
auto的自动推导,用于从初始化表达式中推断出变量的数据类型。
//C++98
int a = 10;
string s = "abc";
float b = 10.0;
vector<int> c;
vector<vector<int> > d;
map<int, string> m;
m[1] = "aaa";
map<int, string>::iterator it = m.begin();
//C++11
auto a1 = 10; //a1为int
auto s1 = "abc"; //s1为string
auto b1 = b;
auto c1 = c;
auto d1 = d;
auto e1 = 'a';
int* x = &a1;
auto d1 = x;
auto m1 = m.begin();
auto x=1,y=2; //ok
auto i=1.j=3.14; //compile error
double a2 = 3.144;
const auto a3 = a2; //const double
auto a4 = a2; //double
volatile int c2 = 3;
auto c3 = c2; //int
2.萃取类型decltype
decltype可以通过一个变量或表达式得到类型。
#include <iostream>
#include <vector>
using namespace std;
int add(int a)
{
return ++a;
}
void fun(int a)
{
cout << "call function: [int]\n" << endl;
}
void fun(int *a)
{
cout << "call function: [int*]\n" << endl;
}
int main()
{
//C++11
int aa = 10;
decltype(aa) bb = 11;
string ss = "hello intel";
decltype(ss) ss1 = "hello";
const vector<int> vec(1);
decltype(vec[0]) cc = 1;
decltype(0) dd = vec[0]; //dd是int类型
decltype(add(1)) ee; //int
int a[5];
decltype(a) ff; //int[5]
//decltype(fun) gg; 无法通过编译,是个重载函数
return 0;
}
3.nullptr
空指针标识符nullptr是一个表示空指针的标识,他不是一个整数,这是与我们常用的NULL宏的区别。NULL只是一个定义为常整数0的宏,而nullptr是C++11的一个关键字,一个內建的标识符。
#include <iostream>
#include <vector>
using namespace std;
void fun(int a)
{
cout << "call function: [int]\n" << endl;
}
void fun(int *a)
{
cout << "call function: [int*]\n" << endl;
}
int main()
{
//C++11
fun(NULL); //call function: [int]
fun(nullptr); //call function: [int*]
int* p = NULL;
fun(p); //call function: [int*]
return 0;
}
4.区间迭代range for
C++98和C++11在使用语法上的差异如下:
#include <iostream>
#include <vector>
using namespace std;
int main()
{
//C++98
vector<int> vec(8, 1);
cout << "C++98 range for:" << endl;
for (vector<int>::iterator it = vec.begin(); it != vec.end(); it++)
{
cout << *it << endl;
}
//C++11
cout << "C++11 range for:" << endl;
for (auto d : vec)
{
cout << d << endl;
}
return 0;
}
值得指出的是,是否能够使用基于范围的for循环,必须依赖一些条件。首先,就是for循环迭代的范围是可确定的。对于类来说,如果该类有begin和end函数,那么for_each之间就是for循环迭代的范围。对于数组而言,就是数组的第一个和最后一个元素间的范围。其次,基于范围的for循环还要求迭代的对象实现+ + 和==等操作符。对于STL中的容器,如string、array、map等使用起来是不会有问题的。下面是C++11操作vector和数组的实践:
#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector<int> vec(8, 1);
//C++11
cout << "C++11 value range for:" << endl;
/*d非引用,修改d不会影响vector里的值*/
for (auto d : vec) //d中存储的是vec中的值
{
d = 2;
}
for (auto d : vec)
{
cout << d << endl;
}