C++–STL–C++11语言新特性

C++–STL–C++11语言新特性(C++标准库第2版)

1、nullptr取代0或者NULL

// 假设有两个f重载函数
void f(int);
void f(void*);

f(0);  // 调用f(int)
f(NULL);  // 调用f(int),如果NULL是0的话
f(nullptr);  // 调用f(void*)

2、auto完成类型推导

auto i = 100;  // i is int
vector<string> vec;
auto it = vec.begin();  // it is vector::iterator

3、一致性初始化与初值列

// 一致性初始化,使用大括号
int arr[]{1, 2, 3};
vector<int> vec{2, 3, 4, 5, 6};

// 初值列,{}没有值会被初始化为0或nullptr
int j{};  // j is 0
int *p{};  // p is nullptr

cout << j << " " << p << endl; //  0 0

// 窄化(精度降低或造成数值变动),不可使用{}
int x1{5.1};  // error
int x2(5.1);  // x2 is 5

// 自定义初值列
void print(initializer_list<int> vals)
{
    for(auto it = vals.begin(); it != vals.end(); ++it){
        cout << *it << "\t";
    }
    cout << endl;
}
print({1, 2, 3, 4, 5});
// explicit防止构造函数的隐式转换,例如使用=
class A
{
public:
    explicit A(int value):m_a(value){}
private:
    int m_a;
};

A a(100);  // OK
A b = 100;  // error 

4、for-range循环

for (auto &i : {1, 2, 3, 4})
{
    cout << i << "\t";
}
cout << endl;

vector<string> vec{"123", "456", "789"};
for (const auto &j : vec) 
{
    cout << j << "\t";
}
cout << endl;
// explicit无法通过编译

5、move和右值引用

// 左值:可以获取地址的表达式
// 右值:无法获取地址的对象(常量值、函数返回值、lambda表达式)
int &&x1 = 100;        //正确,字面值常量是右值
//int &&x2 = x1;        //错误,表达式x1是左值
int &&x3 = std::move(x1);    //正确
// STL保证了被搬移者,其值为空

6、新式字符串字面常量

cout << R"(\\n)" << endl;  // R"()"防止转义

7、关键字noexcept

void fun() noexcept;  // noexcept指明函数无法或者不打算抛出异常

8、关键字constexpr

constexpr int a = 100;
cout << a << endl;  // 与const的区别,const只读,而constexpr一直都是常量

9、模板Template特性

// 模板特性
template <typename AnyType>
void Swapr(AnyType& a, AnyType& b);

int main()
{
    // int a = 20, b = 50;
    string a = "123", b = "456";
    Swapr(a,b);
    cout << "a value: " << a << endl;
    cout << "b value: " << b << endl;

    return 0;
}

template<typename AnyType>
void Swapr(AnyType& a, AnyType& b)
{
    AnyType temp;
    temp = a;
    a = b;
    b = temp;
}

10、Lambda函数

auto fun = []{cout << "I'm lambda function!" << endl;};
fun();

// 可以加()指明引入的参数
auto fun1 = [](const int& x){cout << x << endl;};
fun1(100);

// ->指明返回类型
auto fun2 = []() -> double {return 12;};
cout << fun2() << endl;

// []访问外部作用域,[=]值传递,[&]引用传递,也可以个别指明
int a = 10;
string b = " 123";
auto fun3 = [a, &b]{cout << a << b << endl;};
fun3();

11、关键字decltype

unordered_map<string, int> map;
decltype(map)::value_type elem;  // 让编译器找出表达式类型

12、强类型枚举enum class

// 声明day为枚举类型,Mon...Sun为符号常量,0-6
enum day {Mon, Tue, Wed, Thu, Fri, Sat, Sun};
day x = Mon;
day y = day(2);
// 适合配合switch使用
switch(x)
{
    case Mon:
    case Tue:
    case Wed:
    case Thu:
    case Fri: cout << "oh, No" << endl; break;
    case Sat:
    case Sun: cout << "Yeah" << endl; break;
}

// 强类型枚举enum class防止枚举常量暴露外层作用域;
// 以及防止枚举值隐式转换成整型
enum class Color{RED, BLUE, YELLORE};
enum class Color2{RED, YELLOR, GREEN};  // 使用enum报错
// cout << RED << endl;  // 枚举值也不会被隐式转换为整数

你可能感兴趣的:(C++,c++,开发语言,后端)