C++11

auto

可以从初始化表达式中推断出变量的类型,大大简化编程工作。

auto a = 10; a++; cout << a << endl; a = 11;

属于编译器特性,不影响最终的机器码质量,不影响运行效率。

decltype

可以获取变量的类型。

int a = 10; decltype(a) b = 20; // int b = 20;

nullptr

可以解决NULL二义性问题。

void func(int v)
{
    cout << "func(int v)" << v << endl;
}

void func(int *v)
{
    cout << "func(int *v)" << v << endl;
}

int main()
{
    func(0);
    // func(NULL); // 会报错,因为两个函数都匹配。
    func(nullptr);
    return 0;
}

快速遍历

int a[] = {1, 2, 3, 4, 5};
for ( auto i : a ) cout << i << ' ';

更加简洁的初始化数组方式

int a[] = {1, 2, 3, 4, 5};

可以去掉中奖的=号。

int a[]{1, 2, 3, 4, 5};

Lambda表达式

[capture list] (params list) mutable exception-> return type { function body }

capture list:捕获外部变量列表。

params list:形参列表,不能使用默认参数,不能省略参数名。

mutable:用来说用是否可以修改捕获的变量。

exception:异常设定。

return type:返回值类型。

function body:函数体。

有时可以省略部分结构。

[capture list] (params list) -> return type {function body}
[capture list] (params list) {function body}
[capture list] {function body}

int main()
{
    // 返回值 (函数指针)(参数列表)
    // void (*p)() = []
    // 也可以使用auto
    auto p = []
    {
        cout << "func";
    };
    p();
    return 0;
}

复杂点的

int main()
{
    auto p = [](int a, int b) -> int // 这里可以省略 -> int
    {
        return a + b;
    };
    int c = p(1, 2);
    cout << c << endl;
    return 0;
}

捕获外部变量

捕获外面的参数,使得Lambda函数内部可以访问。

值捕获

默认是值捕获,即使在函数调用前修改了外部参数的值,也不会影响Lambda中已捕获参数的值。

int main()
{
    int a = 10, b = 20;
    auto p = [a, b] // 也可以简写成 [=], 如:auto p = [=]
    {
        cout << a << endl; // 这里还是10
        cout << b << endl;
    };
    a = 1;
    p();
    return 0;
}

地址捕获

int main()
{
    int a = 10;
    auto p = [&a] // 可以简写为:auto p = [&]
    {
        a = 1;
    };
    p();
    cout << a << endl; // a = 1,p函数修改了a的值
    return 0;
}
int main()
{
    int a = 10, b = 20;
    // a是地址捕获,其他的是值捕获
    auto p = [=, &a]
    {
        a = 1;
    };
    p();
    cout << a << endl;
    return 0;
}

mutable

允许修改捕获变量的值,注意,外部变量的值不受影响,除非是地址捕获。

int main()
{
    int a = 10, b = 20;
    auto p = [a] () mutable
    {
        a = 1;
    };
    p();
    cout << a << endl;
    return 0;
}

C++14

泛型Lambda表达式

auto func = [](auto v1, auto v2) { return v1 + v2; };

对捕获的变量进行初始化

int a;
auto func = [a = 10]()
{
  	cout << a << endl;  
};
func();
// 这里仍然未初始化
cout << a << endl;

C++17

可以进行初始化的ifswitch语句。

int main()
{
    if ( int a = 10; a > 10 )
    {
        cout << a << endl;
    }
    else if ( int b = 20; b < a )
    {
        cout << a << ' ' <<  b << endl;
    }
    
    switch ( int a = 10; a )
    {
        case 10:
            break;
        default:
            break;
    }
    return 0;
}