如何优(装)雅(B)地使用C++
介绍一些冷门的C++语法特性,供压行选手使用(雾)
前置知识
- C++基础语法(
- 运算符重载
template
的初级应用(什么是初级呢,会用template
写max
就好)functor
(只会提及,了解即可)
正文
1.匿名函数(lambda表达式)
需要C++11
比赛可用:★★★☆☆
代码简化:★★★★☆
匿名函数应用于需要使用短函数的场合,或者函数需要修改此作用域内(非全局作用域)的局部变量的场合。
常见用法是使用
sort
的时候,需要传入一个cmp
数组,但是自行定义又太过于繁琐,这时候可以直接使用lambda
表达式。
基础格式:
[捕捉局部变量列表](参数){函数体}
例如,如果需要给
point
排序,以x
为第一关键字从大到小排序,可以这么写:sort(pi+1,pi+1+n,[](point a,point b){
if(a.x != b.x)
return a.x<b.x;
return a.y<b.y;
});
lambda
本质是一种functor
,即重载了operator ()
的类。lambda
表达式作为返回值,然后就不想了lambda
表达式来玩一些骚操作,然后被类型系统劝退了2.语句内嵌表达式
无特殊要求
比赛可用:★★★★★
代码简化:★★☆☆☆
语句内嵌表达式应用于需要在传入一个值的场合运行一个表达式的情况。这么说可能有点抽象,具体来说,比如我们要执行以下程序段:
int a = query(1,1,n,l1,r1);
int b = query(1,1,n,l2,r2);
printf("%d",a+b+a*b);
这时候,就可以使用这样的语法来代替:
printf("%d",({
const int a = query(1,1,n,l1,r1);
const int b = query(1,1,n,l2,r2);
a+b+a*b;
}));
也就是说,语句内嵌表达式的格式是这样子:
({
语句1;
语句2;
...
语句n;
})
整个语句内嵌表达式的值就是最后一个语句(或者表达式)的值。其中语句可以是选择语句或循环语句,但是必须以一个单独的语句(或表达式)结尾作为值。
使用这种语法,
可以省掉一个 可以强调
if
的大括号a
和b
的临时变量的地位(即a
和b
只是为了计算而临时定义的),理论上来说会使程序更加清晰,实际上未必(糊)。不建议在其中使用过于复杂的逻辑。(会让代码看起来很乱,结构很不清晰紧凑)
这个语法看起来是
C++11
新增的好东西,其实在C99
就有了(甚至可能更早),所以不用担心比赛的时候不能用。3.复合字面量
无特殊要求
比赛可用:★★★★★
代码简化:★★★★☆
不想写构造函数?没关系!对于结构体,你可以使用复合字面量!
一看就懂!包学包会!省个函数!压行必备!
struct point
{
int x;
int y;
};
int main()
{
point a = (point){1,2};
printf("%d %d\n",a.x,a.y);
}
输出:
1 2
stl::initializer_list<>
初始化结构体的应用,直到我看到了C的标准附录:效率问题
运行结果(皆重复100次):
操作 | 传统 | 文中 |
---|---|---|
1:排序 个数 | 10.16s | 7.432s |
2:编译后查阅汇编码 | N/A | N/A |
3:不想测了,反正差不多 | N/A | N/A |
注:2中结果为汇编码相同
(操作1 文中方法比较快的原因似乎是
lambda
表达式会直接内联汇编进去,而函数指针不会)
评论
发表评论