C++读书笔记(牛客网)

 

1.constexpr变量:声明为constexpr的变量一定是一个常量,新标准允许定义一种特殊的constexpr函数使得编译时就可计算结果,这样就能用constexpr函数去初始化constexpr变量。

2.类型别名:1.typedef     2.using SI = Sales_item;  //SI是Sales_item的别名声明,把等号左侧的名字规定成等号右侧类型的别名 3.using可以起模板别名

3.auto:auto让编译器通过初始值来推算变量类型。auto i = 0, *p = &i; //ok     auto sz = 0, pi = 3.14; //error, 类型不统一

auto一般会忽略顶层const,保留底层const。如果希望保留顶层const,要明确指出 const auto p = ci;

设置类型为auto的引用时,初始值中的顶层const属性保留。

底层 * 顶层: int const * const

4.decltype:类型指示符,顶层const能被保留,decltype((i)) d; //error, 对表达式套括号的结果永远是引用,不套括号则仅当i是引用时,才是引用。

5.范围for语句:for(declaration: expression) statement

expression是一个对象,表示一个序列;declaration部分定义一个变量,被用于访问序列中的基础元素,每次迭代该变量会被初始化为expression的下一个元素值。

如:

1 vector<int> v = {0, 1, 2, 3, 4, 5};
2 for(auto &r: v)
3     r *= 2;

6.标准库begin()和end():begin(arr)返回指向arr首元素的指针, end(arr)返回指向arr尾元素下一位置的指针。

7.列表初始化返回值:vector<string> f(){ if(true) return {};  else return {"fun", "ok"}; }

8.定义尾置返回类型:任何函数的定义都能使用尾置返回类型,但对返回类型比较复杂的函数最有效,比如返回数组的指针或数组的引用。尾置返回类型跟在形参列表后,并以->开头,本应该出现返回类型的地方则放置auto。比如:

auto func(int i) -> int(*) [10];//返回类型为int(*)[10]

9.容器的列表初始化:vector<const char*> articles = {"a", "an", "the"};

10.容器的emplace操作:emplace_frnont, emplace, emplace_back, 这些操作构造而不是拷贝元素,c.emplace(iter, "999-9999"); //向iter指向的位置插入以"999-9999"为构造参数的元素

11.lambda

[ capture ] ( params ) mutable exception attribute -> ret { body } (1)
[ capture ] ( params ) -> ret { body } (2)
[ capture ] ( params ) { body }

(3)

[ capture ] { body } (4)

mutable 修饰符说明 lambda 表达式体内的代码可以修改被捕获的变量,并且可以访问被捕获对象的 non-const 方法。

exception 说明 lambda 表达式是否抛出异常(noexcept),以及抛出何种异常,类似于void f(throw(X, Y)。

attribute 用来声明属性。

[]      // 不捕获任何外部变量
[=]     // 以值的形式捕获所有外部变量
[&]     // 以引用形式捕获所有外部变量
[x, &y] // x 以传值形式捕获,y 以引用形式捕获
[=, &z] // z 以引用形式捕获,其余变量以传值形式捕获
[&, x]  // x 以值的形式捕获,其余变量以引用形式捕获
另有一点需注意。对于 [=] 或 [&] 的形式,lambda 表达式可直接使用 this 指针。但对于 [] 的形式,如果要使用 this 指针,必须显式传入:[this]() { this->someFunc(); }(); 

lambda后紧接();表示直接调用函数,括号内为参数。例:

http://wenku.baidu.com/view/77cd432e647d27284b73514b.html?from=search

    std::vector<int> c { 1,2,3,4,5,6,7 };
    int x = 5;
    c.erase(std::remove_if(c.begin(), c.end(), [x](int n) { return n < x; } ), c.end());
    for (auto i: c) {
        std::cout << i << ' ';
    }
    std::cout << endl;

    // the type of a closure cannot be named, but can be inferred with auto
    auto func1 = [](int i) { return i+4; };
    std::cout << "func1: " << func1(6) << '\n';

    // like all callable objects, closures can be captured in std::function
    // (this may incur unnecessary overhead)
    std::function<int(int)> func2 = [](int i) { return i+4; };
    std::cout << "func2: " << func2(6) << '\n';

    string result = [](const string & str) { return "Hello from " + str; }("second Lambda");
    cout << "Result: " << result << endl;
View Code

相关文章: