1:
C++98(1.0)
C++03(TR1)
C++11(2.0)
C++14
2:
C++2.0新特性包括语言和标准库
#include <type_traits>
#include <unordered_set>
#include <forwward_list>
#include <array>
#include <tuple>
#include <regex>
#include <thread>
using namespace std;
3:
看编译器对C++的支持搜索关键字:Compiler support for C++11 and C++14
语法查询 www.cplusplus.com -> Rference
CppRenference.com
标准库全文检索工具 Windows Grep
4:
cout<< __cplusplus <<endl;//如果输出201103就是支持的C++11,如果输出199711就是支持C++03
5:重要的新特性
语言: Variadic Templates *
move Semantics *
auto *
Range-base for loop *
Initializer list
Labdas
...
标准库:type_traits *
Unordered 容器
forward_list *
array *
tuple *
Con-currency
RegEx
...
-------------------------------------------- Variadic Templates *--------------------------------------------
void print() //处理0个参数的函数,没有这个函数,下面的递归会报错
{
}
template <typenmae T, typename... Types> //接受任意个数的类型,类型也是任意的
void print(const T& firstArg, const Types&... args)//
{
count<< firstArg << endl;
print(args...); //递归,最后args为1时分解为1和0,0个参数想要退出就调用上面那个函数。
}
// 在新特性中2和3可以并存,why?
template <typename... Types>
void print(const Types&... args)
{
}
-------------------------------------tuple--------------------------------------------
tuple<>
/|\
|
tuple<string>
string m_head("mico")
/|\
|
tuple<float,string>
float m_head(6.3)
/|\
|
tuple<int,float,string>
int m_head(41)
实现上面功能的代码:
template<typename... Values> class tuple;
//父类
template<>
class tuple<>
{
}
//子类
template<typename Head, template... Tail>
class tuple<Head, Tail...> : private tuple<Tail...> //继承父类
{
typedef tuple<Tail...> inherited;//父类类型的别名,为了构造时给父类传参
pulibc:
tuple() {}
tuple(Head v,Tail... vtail) : m_head(v), inherited(vtail...){}
typename Head::type head(){return m_head;} //获取第一个参数
inherited& tail() {return *this;} //获取后面所有参数
protected:
Head m_head;//比父类多的成员变量
}
例:
tuple<int,float,string> t(41,6.3,"mico");
t.head();// 41
t.tail().head();//6.3
--------------------------------------------不用分开> >了--------------------------------------------
vector<list<int> >;//OK in each C++ version
vector<list<int>>; //OK since C++11
--------------------------------------------可以使用nullptr关键字代替0或NULL--------------------------------------------
void f(int);
void f(void*);
f(0);//调用f(int);
f(NULL);//如果NULL是0就调用f(int),
f(nullptr);//调用 f(void*)
--------------------------------------------auto 作为程序员还是应该用在类型很长或很复杂的情况--------------------------------------------
auto i=42;
double f();
auto d=f();
vector<string> v;
....
auto pos = v.begin();
auto l=[](int x)->bool{
....
}
--------------------------------------------一致性初始化 Uniform Initialization--------------------------------------------
都可以用大括号初始化了。变量后面大括号就是初始化
int va[] {1,2,3};
vaector<int> v{2,3,4,5,6,7,8};
vector<string> cities {"Berlin","New York", "London", "Cairo"};
complex<double> c{4.0, 3.0};
事实:编译器一看到大括号就做出一个initializer_list<T>,它联系至一个array<T,n>。array内的
元素被编译器分解逐一传给函数。但若函数参数就是一个initializer_list<T>,
------------------------------------------------
*********Initializer Lists***************
int i;
int j{};//初始化为0
int* p;
int* q{};//初始化为nullptr
int x1(5.2);// 5
int x2 = 5.2;//5
int x3{5.0};//warming
int x4 = {5.0};//warming
char c1{7};
char c2{99999};///warming
std::vector<int> v1 {1,2,3,4,5};
std::vector<int> v2 {1,2.3,3,4,5.6};//warming
----------------------------------------------------------
以上都是initializer_list<>的支撑
//如果我们想接受任意个数的参数,同类型
void print(std::initializer_list<int> vals)
{
for (auto p = vals.begin(); p != vals.end(); ++p)
{
std:cout<< *p << "\n";
}
}
print({1,3,5,7,9});
--------------------------------------------右值引用--------------------------------------------
P23:右值引用(一种数据传递机制:新增了可以同时浅拷贝和深拷贝,通过判断是不是右值来区别调用。
原来我们只能有一个拷贝函数,所以要么深拷贝要么浅拷贝,通常深拷贝)
s1 + s2 = s2; //竟然通过编译
string() = "world"; //竟然可以对临时对象赋值
complex<int> c1(3,8), c2(1,0);
c1 + c2 = complex<int>(4,9);//竟然通过编译
complex<int>() = complex<int>(4,9);//竟然通过编译
临时对象会被编译器当作右值!!
c.insert(ite, 类型(buf));// 强转的是临时变量
//copy
insert(...,&x);
//copy构造
Mystring(const Mystring& str) //深拷贝
: 初始化列表
{ ...
}
//move
insert(...,&&x);
//move构造
Mystring(const Mystring&& str) noexcept //浅拷贝
: 初始化列表
{ ...
}
一个变量可当左值也可以当右值,如何只当右值? std::move(变量)
临时对象会自然而然是右值!
M c1(c);//调copy构造
M c2(std::move(c1));//调move构造
M c3(c1);//调copy构造
P24:
void f(int& i){cout<<"&";}
void f(int&& i){cout<<"&&";}
void forward(int&& i){cout<<"&&"; f(i);}
int a = 0;
f(a);//&
f(1);//&&
f(move(a));//&&
forward(2);//&& & 2是右值,传到上面却变为左值了,所以上面的forward是不完美的设计
forward(move(a));//&& & move(a)是右值,传到上面却变为左值了,所以上面的forward是不完美的设计
P25: 右值引用的构造的写法
class Mystring
{
//新增一个右值引用的构造
Mystring(Mystring&& str) noexcept
: _data(str._data), _len(str._len)
{
str._len = 0;
str._data = NULL;
}
Mystring& operator = (const Mystring&& str)
{
if (this != &str)
{
if (_data) delete _data;
_len = str._len;
_data = new char[_len + 1];
memcpy(_data, str._data);
_data[_len] = '\0';
}
return *this;
}
};
P27:新容器
原有的:
Vector: OOOOO->
Deque:<-OOOO->
List: =O=O=O=O=
Set/Multiset: O
O O
O O O O
Map/Multimap: OO
OO OO
OO OO OO OO
新增的:
Array:OOOOOOO
ForwardList: ->O->O->O->O->
Unordered Set/Multiset:O O O
O OO
Unordered Map/Multimap:OO OO OO
OO OOOO
P30:hash function 用来得到哈希值的函数
cout<< hash<int>()(123); //123 //第一个()是创建临时对象。第二个()是传参
cout<< hash<long>()(123L); //123
cout<< hash<const char*>()("Ace"); //5075396
cout<< hash<char>()('A');//65
cout<< hash<float>()(3.141592653);//1294047319
hash<double> p;
cout<< p(3.141592653);//3456236477
void* pi = (void*)(new int(100));
cout<< hash<void*>()(pi);//4079456
//新增
cout<< hash<string>()(string("Ace"));//1765813650
P31: tuple
tuple<string,int,int,complex<double>> t;
cout<< sizeof(t) <<endl;// 32
tuple<int,float,string> t1(41,6.3,"nico");
cout<< get<0>(t1) << get<1>(t1) << get<2>(t1) << endl;
auto t2 = make_tuple(22,44,"stacy");
get<1>(t1) = get<1>(t2);
t1 = t2;
tuple<int,float,string> t3(77,1.1,"more light");
int i1;
float f1;
string s1;
tie(i1,f1,s1) = t3;
typedef tuple<int,float,string> TupleType;
cout<< tuple_size<TupleType>::value; // 3
tuple_element<1,TupleType>::type f1 = ?
for循环
for( 声明 : coll ) {}
for (int i : {1,2,3,4,5})
{ cout<<i;
}
vector<double> vec;
for (auto elem : vec)
{ cout<< elem ;
}
for (auto& elem : vec)
{ elem *= 3;
}
以上的简化本质是:
For (auto p = coll.begin(), end = coll.end(); p != end; ++p) {}
For (auto p = begin(coll), end = end(coll); p != end; ++p) {}
--------------------------------------------Explict关键字用来表示不能隐转。用于构造--------------------------------------------
Class C
{
Explicit C(string){}
}
Vector<string> a;
For(const C& emem : a); 报错!!
=Default =delete delete表示不想要,default表示想要一个默认的。
Class Zoo
{
Zoo(const Zoo&) = delete;
Zoo(Zoo&&) = default;
Zoo& operator = (const Zoo&) = default;
Zoo& operator = (const Zoo&&) = delete;
};