C++ 11特性
1.auto:自动类型推导
编译时对变量进行类型推导,不会对程序的运行效率造成影响;
不会影响编译速度,因为编译时也要右侧推导,然后判断与左侧是否匹配;
通过初始化表达式进行类型推导。
1. auto a; // error 如果没有初始化表达式,就无法确定a的类型 2. auto i = 1; 3. auto d = 1.0; 4. auto str = "hello world"; 5. auto ch = 'a'; 6. auto func = less<int>(); 7. vector<int> iv; auto ite = iv.begin(); 8. auto p = new foo(); // 对自定义类型进行类型推导 9. 模板中应用: template <typename Product, typename Creator> void processProduct(const Creator& creator) { Product* val = creator.makeObject(); } // 使用auto templete <typename Creator> void processProduct(const Creator& creator) { auto val = creator.makeObject(); }
2. decltype:从一个变量或表达式中得到类型
int x = 3; decltype(x)y = x; // 应用 template <typename Creator> auto processProduct(const Creator& creator) -> decltype(creator.makeObject()) { auto val = creator.makeObject() }
3. nullptr:空指针常量
#ifdef __cplusplus ---简称:cpp c++ 文件 #define NULL 0 #else #define NULL ((void *)0) #endi
解决C++中NULL的二义性,因为NULL实际上代表0;
C++中不能将void *类型的指针隐式转换成其他指针类型。
4. 序列for循环
遍历数组、容器、string以及由begin和end函数定义的序列(即有Iterator)
map<string, int> m{{"a", 1}, {"b", 2}, {"c", 3}}; for(auto p : m) { cout<<p.first<<":"<<p.second<<endl; }
5. Lambda表达式
创建并定义匿名的函数对象,简化编程。
// 语法 // [函数对象参数](操作符重载函数参数)->返回值类型{函数体} vector<int> iv{5, 4, 3, 2, 1}; int a = 2, b = 1; for_each(iv.begin(), iv.end(), [b](int &x){cout<<(x+b)<<endl;}); // (1) for_each(iv.begin(), iv.end(), [=](int &x){x *= (a+b);}); // (2) for_each(iv.begin(), iv.end(), [=](int &x)->int{return x*(a+b);}); // (3)
[]:可取得的全局变量
(1):b指函数可得到在Lambda表达式外的全局变量
(2)(3):=是可取得所有的外部变量
():每次调用函数时传入的参数
->后加上的是Lambda表达式返回值的类型
6. 变长参数的模板
// pair可使用make_pair构造 auto p = make_pair(1, "C++ 11"); // 变长参数模板,tuple(1个N元组) auto t1 = make_tuple(1, 2.0, "C++ 11"); auto t2 = make_tuple(1, 2.0, "C++ 11", {1, 0, 2}); // Print函数 template<typename head, typename... tail> void Print(Head head, typename... tail) { cout<<head<<endl; Print(tail...); } // Print中可传入多个不同种类的参数 Print(1, 1.0, "C++ 11");
7. 智能指针
C++11之后智能指针分为了三种:shared_ptr, unique_ptr, weak_ptr
C++11之后的智能指针的构造函数都有explict关键词修饰,表明它不能被隐式的类型转换。
shared_ptr<int> p1 = new int(1024); //这种是不行的,因为等号右边是一个int*的指针,因为有explict修饰,所以它不能被隐式的转换为shared_ptr<int>的类型 shared_ptr<int> p2(new int(1024)); //这种是直接采用了初始化的形式