\(\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 }
- \(\text{capture list}\):捕获外部变量列表。不可以省略。
- \(\text{params list}\):形参列表。不可以省略。
- \(\text{mutable}\) 指示符:用来说用是否可以修改捕获的变量。可以省略。
- \(\text{return type}\):返回类型。编译器可以根据 \(\text{return}\) 语句推断返回类型,但需要注意同时 \(\text{return}\) 两种类型就会报错,可以省略。
- \(\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\) 是值捕获,其余变量是引用捕获。一些组合也类似,就不讲了。