C++11 是 C++的一个版本,由C++03改进而来,原来计划是在2010年前发布,所以经常可以看到C++0x。C++11添加了很多非常好用的特性,甚至被人们认为是一门新的语言。C++11在GCC 4.8中支持基本完善。以下内容为转载,添加了一些笔记。
auto,decltype,for,nullptr
如果编译器在定义一个变量的时候可以推断出变量的类型,不用写变量的类型,你只需写auto即可
auto str = "sissie";
assert(typeid(str) == typeid(const char *));
auto处理引用时默认是值类型,可以指定&作为修饰符强制它作为引用,auto自动获取指针类型,也可以显示地指定指针类型
int& foo();
auto i = foo(); // int
auto& ri = foo(); // int&
int* bar();
auto pi = bar(); // int*
auto* pi = bar(); // int*
在迭代器中使用auto,简化代码
std::vector
vs{{"sissie", "robin", "playjokes", "sky", "hatlonely"}}; for (auto it = vs.begin(); it != vs.end(); ++it) { std::cout << *it << ", "; }
在模板中使用auto
template
void makeAndProcessObject(const Builder& builder) { BuiltType val = builder.makeObject(); // do stuff with val } MyObjBuilder builder; makeAndProcessObject
(builder); // 使用auto只需要一个模板参数,让编译器自动推导 template
void makeAndProcessObject(const Builder& builder) { auto val = builder.makeObject(); // do stuff with val } MyObjBuilder builder; makeAndProcessObject(builder);
decltype 返回操作数的类型,可以对基本上任何类型使用decltype,包括函数的返回值
int ia[10];
decltype(ia) ib; // int ib[10];
新的函数返回值声明语法,把返回类型放在函数声明的后面,用auto代替前面的返回类型
// 这两种函数声明方式等效
int multiply(int x, int y);
auto multiply(int x, int y) -> int;
// 返回auto
template
auto makeAndProcessObject(const Builder& builder) -> decltype(builder.makeObject()) { auto val = builder.makeObject(); // do stuff with val return val; }
区间迭代,for循环遍历容器
std::vector
vs{{"sissie", "robin", "playjokes", "sky", "hatlonely"}}; for (const auto& name: vs) { std::cout << name << ", "; }
nullptr 是C++11中新加的关键字,用来表示空指针,替代原来的NULL,nullptr不能转换成int
lambda 表达式
C++11中得lambda表达式用来定义和创建匿名函数,lambda表达式语法形式如下:
[ capture ] ( params ) mutable exception attribute -> ret { body } // (1)
[ capture ] ( params ) -> ret { body } // (2)
[ capture ] ( params ) { body } // (3)
[ capture ] { body } // (4)
(1) 是完整的 lambda 表达式形式
(2) const 类型的 lambda 表达式,该类型的表达式不能改捕获(“capture”)列表中的值
(3) 省略了返回值类型的 lambda 表达式,但是该 lambda 表达式的返回类型可以按照下列规则推演出来:
如果 lambda 代码块中包含了 return 语句,则该 lambda 表达式的返回类型由 return 语句的返回类型确定。 如果没有 return 语句,则类似 void f(…) 函数
(4) 省略了参数列表,类似于无参函数 f()
capture:capture 为捕获的lambda所在作用域范围内可见的局部变量列表
[a,&b] a变量以值的方式呗捕获,b以引用的方式被捕获 [this] 以值的方式捕获 this 指针 [&] 以引用的方式捕获所有的外部自动变量 [=] 以值的方式捕获所有的外部自动变量 [] 不捕获外部的任何变量
params:参数列表
mutable exception attribute:lambda是否可以更改捕获变量以及是否有异常抛出
mutable 修饰符说明 lambda 表达式体内的代码可以修改被捕获的变量,并且可以访问被捕获对象的non-const 方法 exception 说明 lambda 表达式是否抛出异常(noexcept),以及抛出何种异常,类似于void f() throw(X, Y) attribute 用来声明属性
ret:返回类型
body:函数体
// 数组累加
std::vector
vi{{1, 2, 3, 4, 5, 6, 7, 8, 9}}; int total = 0; std::for_each(vi.begin(), vi.end(), [&total](int i) { total += i; }); // 数组绝对值 // 单一的return语句,编译其可以推导出返回类型,多个return语句需要显示指定返回类型 std::transform(vi.begin(), vi.end(), [](int i) -> int { if (i < 0) { return -i; } else { return i; } }); // mutable size_t i = 42; auto f = [i]() mutable { return ++i; }; i = 0; std::cout << f() << std::endl; // 43 std::cout << f() << std::endl; // 44
初始化列表
C++11新添加初始化列表std::initializer_list<>类型,可以通过{}语法来构造初始化列表
// 容器初始化
// {1, 2, 3, 4, 5}实际上是一个std::initializer_list
类型 std::vector
vi = {1, 2, 3, 4, 5}; std::vector
vs{{"sissie", "robin", "playjokes", "sky", "hatlonely"}}; std::map
mis = { {1, "c"}, {2, "java"}, {3, "c++"} }; // 初始化列表参数 void print_initializer_list(std::initializer_list
il) { for (auto i: il) { std::cout << i << ", "; } std::cout << endl; } print_initializer_list({1, 2, 3, 4, 5, 6}); // 返回初始化列表 std::vector
my_array() { return {"sissie", "robin", "playjokes", "sky", "hatlonely"}; }
类
加入两个新的标识符:
override,表示函数应当重写基类中的虚函数; final,表示派生类不应当重写这个虚函数
class B
{
public:
virtual void f(int) {std::c