在 C++ 98/03 标准中,类模板可以有默认的模板参数,但是却不支持函数的默认模板参数:
1 | template <typename T, typename U = int, U N = 0> |
现在这一限制在 C++11 中被解除了,上面的 func 函数在 C++11 中可以直接使用。
函数模板的默认模板参数在使用规则上和其他的默认参数也有一些不同,它没有必须写在参数表最后的限制。甚至于,根据实际场景中函数模板被调用的情形,编译器还可以自行推导出部分模板参数的类型(优先于默认类型)。
在 C++ 98/03 标准中,类模板可以有默认的模板参数,但是却不支持函数的默认模板参数:
1 | template <typename T, typename U = int, U N = 0> |
现在这一限制在 C++11 中被解除了,上面的 func 函数在 C++11 中可以直接使用。
函数模板的默认模板参数在使用规则上和其他的默认参数也有一些不同,它没有必须写在参数表最后的限制。甚至于,根据实际场景中函数模板被调用的情形,编译器还可以自行推导出部分模板参数的类型(优先于默认类型)。
在泛型编程中,可能需要通过参数的运算来得到返回值的类型。考虑下面这个场景:
1 | template <typename R, typename T, typename U> |
我们并不关心 a+b 的类型是什么,因此,只需要通过 decltype(a+b) 直接得到返回值类型即可。但是像上面这样使用十分不方便,因为外部其实并不知道参数之间应该如何运算,只有 add 函数才知道返回值应当如何推导。
auto 和 decltype 关键字都可以自动推导出变量的类型,但它们的用法是有区别的:
1 | auto varname = value; |
其中,varname 表示变量名,value 表示赋给变量的值,exp 表示一个表达式。
auto 根据=
右边的初始值 value 推导出变量的类型,而 decltype 根据 exp 表达式推导出变量的类型,跟=
右边的 value 没有关系。
另外,auto 要求变量必须初始化,而 decltype 不要求。这很容易理解,auto 是根据变量的初始值来推导出变量类型的,如果不初始化,变量的类型也就无法推导了。decltype 可以写成下面的形式:
1 | decltype(exp) varname; |
auto 的一个应用就是当我们不知道变量是什么类型,或者不希望指明具体类型的时候,比如泛型编程中。我们看例子:
跳跃:短按小跳(一般用于连招),长按大跳
切换武器:被振刀后按住1或2(振落的槽位),滚动鼠标滚轮选择新武器(个人感觉还是Tab顺手)
加速下落:在空中按住C加速下落,防止被射
喝药蹲伏:修武器时不可移动,嗑药不断按C蹲伏,避免远程爆头;或者在树干上静止喝药
炮台箭头:小地图上若看见炮台箭头在动,说明有人
紫色草丛:蹲下隐身后别人看不见,但是喝药会发光和有声音
刷新二段跳:空中振刀、钩锁都可以刷新二段跳
替换装备:捡东西按3替换装备(如高级甲换低级甲),不会被其他E给挡住
绝大多数情况下优先打药,其次拉人,最后追人
习惯性记一下附近可替换的甲(例如空投)
回血粉回血是固定数值,而体力魂玉是按装上时的百分比计算
1 | System.out.println(0.0 == -0.0); // true |
在集合中遇见0.0和-0.0时,由于自动装箱,导致两个在绝对数值上相等的数据,放入集合时表现出不相等。
State 混入 AutomaticKeepAliveClientMixin,同时 wantKeepAlive 返回 true。
这样使用 TabView 或者 PageView 切换页面时,ListView 等 Stateful 控件的状态(如滚动位置)都会保留下来。
1 | Widget build(BuildContext context) { |
问题描述:编号为 1-N 的 N 个士兵围坐在一起形成一个圆圈,从编号为 1 的士兵开始依次报数(1,2,3…这样依次报),数到 m 的 士兵会被杀死出列,之后的士兵再从 1 开始报数。直到最后剩下一士兵,求这个士兵的编号。
解决方法:最暴力的就是用环形链表,被选中就移除,时间复杂度为 O(n * m)
,空间复杂度是 O(n)
。
例如:链表:1->2->3->4->5->6->7->8->null, K = 3。调整后:3->2->1->6->5->4->7->8->null。
其中 7,8不调整,因为不够一组。
有时候需要根据条件进行类型定义,比如下面这种情况:
1 | struct test_struct |
编译会报错 error: ‘AAA’ was not declared in this scope。
这个时候就可以用std::conditional
来做, 有两种方式:
volatile这个关键字可能很多朋友都听说过,或许也都用过。在Java 5之前,它是一个备受争议的关键字,因为在程序中使用它往往会导致出人意料的结果。在Java 5之后,volatile关键字才得以重获生机。
volatile关键字虽然从字面上理解起来比较简单,但是要用好不是一件容易的事情。由于volatile关键字是与Java的内存模型有关的,因此在讲述volatile关键之前,我们先来了解一下与内存模型相关的概念和知识,然后分析了volatile关键字的实现原理,最后给出了几个使用volatile关键字的场景。
这里使用的是 QuaZip 方案。它调用了 zlib1.dll,如果是32位,直接编译 QuaZip 即可,默认就是32位。
如果是64位,不兼容的 zlib1.dll 会导致编译失败,需要自己编译 zlib。
一,在桌面新建一个文件
文件名随意,但必须带有.desktop的后缀名。
1 | cd 桌面/ |
二,在文件中写入如下内容
1 | [Desktop Entry] |
三,给文件赋予可执行权限
1 | 1 chmod a+x /home/username/Desktop/app.desktop |
需要接收键盘事件,但是又不能有界面
1 | int main(int argc, char *argv[]) |
1、首先需要在main方法中注册,使用installEventFilter方法把这个类的指针传进去
2、在Test类中重写eventFilter方法,这样就可以进行监听了
3、在eventFilter中进行自己的逻辑处理
1 | QLockFile *lockFile = new QLockFile("temp/appName.app.lock"); |
1、QLockFile的构造函数的参数就是指定一个锁文件的地址
2、tryLock的参数为等待时间
3、如果程序没有启动则对文件上锁,如果启动则退出
外部输入的 \u1234
在代码里相当于 \\u1234
,只是普通的字符串,而不是 Unicode,需要单独替换一遍:
1 | QString filename = "\\u6211\\u662f\\u4e2d\\u6587"; |