\(\cal{C}\)\(\text{++}\)

函数的默认参数

默认参数除了使用数值常量指定,也可以使用表达式指定:

int Value=233;
void TellTheTruth(int ET,int make,int shit=Value) {
    cout<<ET<<make<<shit;
}

需要注意的是,默认参数只能放在形参列表的最后,而且一旦为某个形参指定了默认值,那么它后面的所有形参都必须有默认值。

\(\cal{C}\)\(\text{++11}\)

新的空指针 —— \(\text{nullptr}\)

因为 \(\text{NULL}\) 也可以相当于 \(0\),所以可以避免一些错误。

\(\text{constexpr}\)

使用 \(\text{constexpr}\) 定义常量,可以帮助你检查是否为常量表达式,就像这样:

int a;
constexpr int b=a+233;

此时就会报错。

\(\text{auto}\)

\(\text{auto}\) 可以在一条语句声明多个变量,但它们的数据类型必须相同。

其次,\(\text{auto}\) 一般会忽略引用:

int a=0,&b=a;
auto c=b;

此时的 \(c\) 是一个整型,其值为 \(0\)。对它的修改和 \(a,b\) 没有半毛钱关系。

\(\text{decltype}\)

使用 \(\text{decltype}\) 可以从表达式中推断出要定义变量的类型,且不用表达式的值去初始化变量。比如:

int a=0;
decltype(a) b; // b 的类型为整型

不过,\(\text{decltype}\) 只会用表达式的返回值进行推断,并不会执行表达式。又比如:

int function() {
    cout<<"xyyzka!"<<endl;
    return 233;
}
decltype(function()) a;

此时 function() 并不会被真正执行。

另外,\(\text{decltype}\) 还可以处理一个 \(\text{auto}\) 的问题 —— 无法得到引用类型。就像这样:

int a=0,&b=a;
decltype(b) c;

此时 \(c\) 的类型为 int&

另外,如果加上 (),就可以得到此数据类型的引用:

int a;
decltype((a)) b; // b 的类型为 int&

尾置返回类型

比如返回一个二维数组:

auto function(int x) -> int(*)[10][10] {
    // Do something...
}

这个可以配合 \(\text{decltype}\) 食用:

auto function(int x) -> decltype(x) {
    // Do something...
}

\(\text{Lambda}\) 表达式

基本构成:

[capture list] (params list) mutable exception -> return type { function body }
  1. \(\text{capture list}\):捕获外部变量列表。不可以省略
  2. \(\text{params list}\):形参列表。不可以省略
  3. \(\text{mutable}\) 指示符:用来说用是否可以修改捕获的变量。可以省略
  4. \(\text{return type}\):返回类型。编译器可以根据 \(\text{return}\) 语句推断返回类型,但需要注意同时 \(\text{return}\) 两种类型就会报错,可以省略
  5. \(\text{function body}\):函数体。不可以省略

一般可用于简化排序:

sort(vec.begin(),vec.end(),[](int a,int b) { return a>b; });

\(\text{Update on 2022.7.27}\):写这篇文章过去这么久了,竟然现在才发现自己没学懂 qwq……感谢 \(\sf SpadeZ\) 大佬对我 \(\mathcal{C}\text{++}\) 语法知识的降维打击 🥲。

问题大概是在一个 struct 中的成员函数内进行排序时,需要用到结构体内部的变量。此时即使 struct 定义在全局,内部变量相对于成员函数也不是全局变量。你可以在 \(\text{capture list}\) 中添加 & 或者填入 this.

值捕获

被捕获变量的值在 \(\text{Lambda}\) 表达式创建时 通过值拷贝的方式传入,随后对该变量的修改不会影响到 \(\text{Lambda}\) 表达式内部的值。

int a=1,b=2,c=3;
auto function = [a]() { /* Do something */ };

这时就可以在函数内部使用 \(a\) 了。

如果想要使用所有的局部变量呢?

int a=1,b=2,c=3;
auto function = [=]() { /* Do something */ };

另外,如果实在想在函数内修改值,可以加上 \(\text{mutable}\)

int a=1,b=2,c=3;
auto function = [=]() mutable { /* Do something */ };

但此时对变量的修改也不会影响到函数之外。

引用捕获

在前面加上 & 即可,如果想要使用所有的局部变量,也可以这样写:

int a=1,b=2,c=3;
auto function = [&]() { /* Do something */ };

混合捕获

比如这个:

int a=1,b=2,c=3;
auto function = [&,a]() { /* Do something */ };

\(a\) 是值捕获,其余变量是引用捕获。一些组合也类似,就不讲了。

posted on 2021-09-28 17:57  Oxide  阅读(56)  评论(0编辑  收藏  举报