C++11新特性总结

总结自《C++标准库》(第2版)

Template表达式内的空格可以去掉

旧式写法:vector<list<int> >;
新式写法:vector<list<int>>;

nullptr新关键字表示空指针

允许使用nullptr取代0或者NULL,代表一个pointer,并且不会转换成任何整数类型。避免用NULL给指针后传参时导致的anbiguous。

void f(int);
void f(void*);

f(0);  //调用f(int);
f(NULL); //调用f(int);
f(nullptr); //调用f(void*);

auto完成类型自动推导

auto声明的变量会根据其初始化值的类型推导出变量的类型。一定要一个初始化操作

auto i=42;  //i的类型为int

auto在类型或表达式很复杂时很有用,如lambda表达式中或者各种迭代器中。

花括号进行一致性初始化

任何初始化动作都可以使用花括号进行初始化赋值,但是初始过程中不允许出现窄化(降低精度或造成数值变动)现象。

vector<int> v{2,3,4,5,6};  //OK
int a{3};   //OK
int b{3.0}; //ERROR:窄化,由double变成int

initializer_list进行传参

可以使用class template std::initializer_list<>用来支持以一系列值进行初始化,在传参过程中,使用花括号包裹传递。

void print(std::initializer_list<int> vals)
{
    for (auto p = vals.begin(); p != vals.end(); ++p)
        cout << *p << endl;
}
print({ 1, 2, 3, 4, 5 });  //调用

for循环新用法

decl是coll集合中的每个元素的声明,当元素在for循环中被初始化为decl,不得有任何显示类型转换。

for(decl:coll)
{
    statement;
}

//示例
vector<int> vals{ 1, 2, 3, 4, 5 };
for (auto v : vals)
{
    cout << v << endl;
}

move和Rvalue Reference右值引用

move操作主要是減少不必要的拷贝和临时对象。
在传递参数过程中可能会出现很多拷贝赋值的过程,但是临时对象本就在后续过程中不会再被使用,大量的拷贝(分配空间再赋值)会浪费很多时间和资源,所以将其改为右值引用的方式,即将自己这片空间的指针指向临时对象所指向的地址,并将临时对象的那个指针设置为不可再用来实现。
std::move()自身不做任何moving工作,只是将实参转成一个rvalue reference。
rvalue(不具名的临时对象只能出现在赋值操作的右侧) reference可以改变此临时对象的内容。

Raw String Literal

使用R"delim(...)delim"的形式写字符序列,可以不用像之前那样想写“\”但是要加转义字符导致写成“\”。

//以下a和b相等,均输出a\b
string a = "a\\b";
string b = R"del(a\b)del";

noexcept

用来指明某个函数无法或不打算抛出异常。“绝不抛出”异常不需要额外开销。

void foo() noexcept(...)

其中noexcept(...)中为true则不抛出异常。

constexpr

可以让表达式和定于编译期。

Variadic Template

template可以接受个数不定的template实参,即三个点,注意递归的结束条件,即第一个void print()函数

void print()
{
}
template<typename T,typename... Types>
void print(const T& firstArg,const Types&... args)
{
    cout << firstArg << endl;
    print(args...);
}
int main()
{
    print(1, 3, "hello world");
    return 0;
}

Alias Template

带别名的模板,和typename比较

template<typename T>
using Vec=std::vector<T,MyAlloc<T>>;
...
Vec<int> coll;   //等价于std::vector<int,MyAlloc<int>> coll;

Lambda

语法:

[...](...){
    ...
};
如
auto foo=[](int args)
{
    cout << args << endl;
};

foo(1);    //输出1

其中方括号表示引入,其内可以指明一个所谓的capture,用来在lambda内部访问“nonstatic对象”。小括号内可以指明参数。如果有返回类型,则在小括号右边加上-> 返回类型即可,如下:

auto foo=[](int args)->int
{
    return args * 2;
};

cout << foo(1) << endl;

lambda表达式可以定义于语句或表达式内部,可以当做inline函数使用,上面的auto foo=相当于给lambda表达式一个名字,叫做foo,然后可以当做正常函数那样调用。

decltype

可以让编译器找出表达式类型

std::map<std::string,float> coll;
decltype<coll>::value_type elem;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值