2017年4月

C++11引入了auto和decltype关键字实现类型推导,通过这两个关键字不仅能方便地获得复杂的类型,还能简化书写,提高编码效率。下面说一下C++中的auto

旧标准

auto其实并不是一个新的关键字,在旧的标准C++98/03中,它代表着“具有自动存储周期的局部变量”。啥意思呢?就是我们平常所说的变量,他与static相对。就是说所有非static类型的都是“具有自动存储期的”。也就是说在旧的标准下。

autoint i =3;//等价于int i=3;

新标准

在C++11中,auto作为一个新的类型指示符(如int,double)来指示编译器的,但是auto申明的变量的类型必须由编译器在编译时期推导出来,也称类型推导。这种类型推导不是C++所独有的,还有很多具备这种能力的语言(如Python,Javascript)。我们先来看一段Python代码

name ="thinkmoon"print"hello,"+ name 

在这里的name是不需要定义类型的,因为这个类型很容易被推导为字符串性,如过要想在C++中实现这种效果,我们可以这样。

#include<iostream>
int main(){
    auto name ="thinkmoon"; 
    std::cout <<"hello,"<< name << std::endl;
    return0;
}

效果是一样的,是不是觉得写起来特别的方便呢?

但是需要注意的是,在C++中这种静态类型推导是发生在编译期间的。而像Python这种动态类型推导却是发生在运行期间的。

auto的基本用法

#include<iostream>
usingnamespace std;
int main(){
auto x =5; 
cout << x << endl;//x被推导为intauto p =newauto(1);    
cout <<"*"<< p <<"="<<*p << endl;//p被推导为
int *constauto*v =&x, u =6; 
cout <<"*"<< v <<"="<<*v <<"\n u="<< u << endl;//v被推导为const int *,u被推导const int
}

对于最后一个类型推导有几个需要注意

  1. v被推导为const int *而这里auto代替int,但是u等于6还是要写的,否则编译器会报错。
  2. u的等号后面只能写整型的变量,否则会报错,因为不能让编译器产生具有二义性的推断。
其实我们学习的时候可以把auto理解为占位符,它只是占着一个位置并不做其它的事情,由编译器将其类型推导出来再用对应的类型去运行,所以这个时候auto的类型推导是不能让编译器产生二义性的。

auto的推导规则

int x =0;auto* a =&x;//auto推导为int,
auto b =&x;//auto推导为int *,即使不申明为指针也能推断为指针
auto& c = x;//auto推导为int,等价于int 
auto d = c;//auto推导为int,auto会抛弃右值的引用类型
const auto e = x;//e是const int类型,
auto f = e;//f是int型constauto&g = x;//g是const 
int & auto & h = g;  //h是const int & 
总结:
  1. 当不申明为引用或者指针时,auto的推导规则会抛弃对应右值的cv限定符(cv-qualifier,const,volatile限定符的总称)。
  2. 当申明为引用或者指针时,auto推导规则会保留右值的cv属性。

auto的限制

  1. auto s
错误原因:s没有明确的类型,auto无法推断。
  1. void fun(auto a=1){….}
错误原因:auto类型推导不能用作函数参数。
  1. auto不能用于非静态成员函数
struct Foo
{
    auto var_1=0;//错误,auto不能用于非静态成员函数
    static const auto var_2=0;//OK,var_2为static const int
}

4. auto无法定义数组

int main()
{
    int arr[10]={0};
    auto aa    = arr; //OK,aa为int *
    auto bb[10]=arr;//error,auto无法定义数组
}

5. auto无法推导出模板参数

Bar<int> bar;
Bar<auto> bb = bar;//error,auto无法推导出模板参数

auto的优势

既然auto的功能特性这么方便,那么它的优势在哪?或者说,我们什么时候使用它能达到神效呢?

  1. 遍历vector
这是一个简单的遍历。
vector<int> vs;for(auto i = vs.begin(); i < vs.end(); i++){......}
其实还可以更简单
for(auto var : vs){.......}
  1. 待补充。。。。。。。嘿嘿!

一听说QQ机器人是不是感觉有点高大上?感觉离自己有点远?不过事实就是如果你想创建,或者说拥有一个QQ机器人确实一件非常容易的事情。

创建方法

1.腾讯QQ自带的QQ小冰

2.利用第三方框架在自己电脑或者windows云主机上挂一个机器人(mypcqq,酷Q等)

这个方法的好处就是可拓展性强,可二次开发,所以我在以后主要介绍这种方法

框架一(mypcQQ)

从功能上看这个框架功能略显强大(拥有撤回检测,气泡设置,卡片消息),但是缺点也很明显那就是不稳定,页面不太友好。

框架二(酷Q机器人)

因为mypcQQ我认为实在是太不稳定了,所以我在以后的QQ机器人二次开发中着重介绍酷Q机器人的二次开发。

酷Q机器人C++SDK解析

酷Q机器人工作原理

  1. 先是QQ服务器端发送数据给酷Q客户端,酷Q根据数据判断是否触发了事件,以及触发了哪类事件,不同类事件都有一个默认的type。
  2. 然后酷Q会根据这个type在JSON中查找所有具有该type的event项目,并将这些项目按照priority从小到大的顺序排列,然后按照顺序依次向你的DLL发送指令。
  3. 指令的内容就是每个event项目所规定的function值,以及该事件的type所决定的必要参数。在你的DLL内部,会先查找指令中指定的function,找到[函数名]正确的函数,然后按[参数列表]规定的顺序代入参数,执行你写的代码。
  4. [参数列表]只规定了参数的数目、顺序和类型,而参数变量名称酷Q是不管的,也就是说只要数目顺序类型正确,参数变量的名称你可以自己修改。比如fromQQ你可以把它改成TheQNumberItFrom,或者abc,都可以,只要你自己方便就行。
  5. 最后,如何命令酷Q执行你需要的动作呢?你需要调用头文件cqp.h中声明的函数。这些函数只进行了声明,其定义在酷Q加载后会在其它DLL中定义,所以VS可能会提示这些函数未定义,但不影响编译生成,请忽视这些提示。

SDK视图

SDK文件解析

appmain.h

插件APPID的定义,内容不多,在编译前,将这里面的CQAPPID也定义为你之前的文件名AppID。规则见 http://d.cqp.me/Pro/开发/基础信息

cqp.h

cqp.h分为常量定义和函数声明两部分。常量定义部分看不懂也没关系,关键是后面的函数声明部分。函数用途按英语意思去用

每一条声明都具有如下格式:

CQAPI([返回值类型]) 函数名;
[函数名]描述了该函数的功能,如果你看不懂英文(你还是放弃吧),JSON中的auth部分的注释有每一个函数英文名的翻译。
CQ_get开头的函数用于向QQ服务器获取一些状态信息(比如获取某个群员的信息),其它函数用于向服务器发送操作指令(比如发送消息)。get类函数返回你想要获取的信息,其它函数返回操作结果。不同的返回值对应的操作结果,在cqp.h的常量定义部分有说明。
你必须按照[参数列表]的规定调用这些函数。

appmain.cpp

这个cpp是最重要的部分,我们平常编写的功能都是在这个cpp里面,根据对应的规则调用,官方SDK里面有详细的注释。

JSON文件

在修改之前,你要明确JSON的作用:这个文件是你的DLL和酷Q之间的交流协议,它规定了酷Q该如何使用你写的DLL。

  • json规则:http://d.cqp.me/Pro/开发
  • event部分:// 事件列表,同一事件类型可重复定义(发布前请删除无用事件)
  • id:这就是个索引,只要保证你所有事件的id不重复即可
  • type:规定酷Q应该在何时触发这个事件。每种事件对应的type值是固定的,只要你设置的type值正确,酷Q就会在正确的时机触发你的事件。事件的名称无关紧要。
  • name:这个就是显示给用户看的,和你的程序没有关系。
  • function:自由定义,但不能重复,而且有格式要求:

1、由英文字母、数字、下划线构成
2、第一个字符不能是数字
3、大小写敏感,大写和小写是不同的
4、不能和这些关键字重名:https://msdn.microsoft.com/zh-cn/library/2e6a4at9.aspx

如果你需要删除一个事件,需要把一对{}内的内容以及之后的逗号完全删除,否则会报错。请注意不要删除[],而且[]内的最后一对{}后不能跟逗号,其它的必须跟逗号。
如果你需要增加新的事件,建议复制粘贴再修改,以免疏忽。

参考链接:https://cqp.cc/t/27173

这篇主要让大家对酷Q有个基本的了解,下一篇做个小例子。

2019.12.6补充

不打算搞小例子了