前言
我使用的书籍是 C++标准库(第二版)
前两章是一些简单介绍,就此略过从第三章开始分享我的学习所得,欢迎讨论和指出不足之处
前提
需要有一定的c++基础知识,基础部分概不介绍
如果你的编译器版本过低,那么在运行C++11时会出现bug,这里给出codeblock更新办法
https://blog.csdn.net/autocyz/article/details/42368147
STL基本知识(大致了解,本书后面章节有详细介绍)
容器,算法,迭代器
https://m.runoob.com/cplusplus/cpp-stl-tutorial.html
模板
https://www.cnblogs.com/yangxiaoping/p/8268209.html
explicit
https://blog.csdn.net/qq_37233607/article/details/79051075
C++11新特性
1.Template表达式
vector<list<int> >; //过去版本两个表达式闭符之间放一个空格
vector<list<int>>; //C++11可以省略空格
2.nullptr
nullptr是个新关键字,它拥有类型std::nullptr_t,定义于。原来当我们定义一个空指针,会将指针赋值为NULL,但是编译器中会被解释成0,即变成了一个int,而赋值为nullptr,指针不会被转换成整数,一直是一个空指针。
3.auto
C++11允许你声明一个变量或对象(object)而不需要指明其类型,只需说它是auto。
auto i = 42;
double f();
auto d = f();
auto i; //ERROR!由于它的类型由初值自动推导,因此必须有初始化操作
也可以为它加上额外的限定符,当遇到类型很长或表达式很复杂时,auto能发挥很大的作用。
4.一致性初始化与初值列
面对任何初始化动作,你都可以使用大括号
某个local变量属于某种基础类型,也会被初始化为0或nullptr
int values[]{1,2,3};
vector<string> cities{"Berlin","London"};
complex<double> c{4.0,3.0};
int i; //未初始化
int j{}; //初始化为0
int* p; //未初始化
int8 q{}; //初始化为nullprt
窄化(narrowing)对大括号不成立
int a(5.3);
int b{5.3}; //ERROR
char c{7};
char d{99999}; //ERROR
vector<int> v1 {1,2,3};
vector<int> v2 {1.0,2,3}; //ERROR
用户自定义类型之初值列
void print (initializer_list<int> vals)
{
for(auto p=vals.begin();p!=vals.end();++p){
cout << *p << endl;
}
}
print ({12,3,5,7,11,13,17});
当“指明实参个数”和“指明一个初值列”的构造函数(ctor)同时存在,带有初值列的那个版本胜出
class P
{
public:
P(int,int); //P p(77,5);
P(initializer_list<int>); //大括号优先使用
};
explicit构造函数如果接受的是个初值列,会失去“初值列带有0个、1个或多个初值“的隐式转换能力
5.Range-Based for循环
C++11引入了一种崭新的for循环形式,可以逐一迭代某个给定的区间、数组、集合内的每一个元素。语法如下:
for( decl : coll ){
statement
}
//例:
for(int i: {2,3,4,5,6}){
cout << i << endl;
}
//等同于
for(auto _pos=coll.begin(),_end=coll.end();_pos!=_end;++_pos){
decl = *_pos;
statement;
}
此外,允许你用寻常的、大小已知的C-style array
int array[] = {1,2,3,4,5};
long sum = 0;
for(int x : array){
sum += x;
}
当元素在for循环中被初始化为decl,不得有任何显式类型转换
6.Move语义和Rvalue Reference
这部分书上是简略介绍,没怎么看懂,推荐这个博客:
https://www.cnblogs.com/harrywong/p/4220233.html
7.新式的字符串字面常量(String Literal )
(1)Raw String Literal允许我们定义字符串序列,以 R"( 开头,以 )" 结尾,可以内含line break,例如:
//表示两个反斜杠和一个n
"\\\\n"
R"(\\n)"
如果要在raw string内写出 )" ,可使用定义符。因此一个完整raw string的完整语法是R"delim(…)delim",delim是个字符序列,最多16个基本字符,不可含反斜线、空格和小括号,例:
R"nc(a\
b\nc()"
)nc";
//等同于
"a\\\n b\\nc()\"\n "
定义正则表达式时raw string literal特别有用
(2)编码的(Encoded)String Literal
只要使用编码前缀,你就可以为string literal定义一个特殊的字符编码。下面这些编码前缀都预先定义好了:
- u8定义一个UTF-8编码。以UTF-8编定的某个给定字符起头,字符类型为const char
- u定义一个string literal,带着类型为char16_t的字符
- U定义一个string literal,带着类型为char32_t的字符
- L定义一个wide string literal,带着类型为wchar_t的字符
例如:
L"hello"
Raw string开头那个R的前面还可以放置一个编码前缀
- 未完待续