std::map 的一个很机智用法

前提是你的编译器必须支持 C++11,否则编译不通过。

#include <iostream>
#include <typeindex>
#include <typeinfo>
#include <string>
#include <map>

class foo
{
public:
    foo()
    {}

    template <typename T>
    void test(T type, std::string msg)
    {
        // 将对应type的msg修改
        map_[typeid(type)] = &msg;
        // 输出对应值
        std::cout << *map_.at(typeid(type)) << std::endl;
    }
private:
    std::map<std::type_index, std::string*> map_;

};

int main()
{
    foo f;
    f.test(2333, "Hello"); // int
    f.test(2333.3, "World"); // double

}

分析

typeid 返回 std::type_index。
foo::test有两个参数,一个是模板参数,一个是 std::string。
map_[typeid(type)] = &msg; 的意思是,设置 map_[typeid(type)] 的值。
这个时候,f.test(2333, "Hello"); 会处理到 int,就会设置 map_[typeid(int)] 的值 (注意int)。
以此类推。这个一般应用在消息处理上(夏幻菊苣说的),或者这个上面。

换行符

为了在写程序的时候不用上网查,窝特地写了一个blog来记录一下,需要的时候看就可以了。

在 Unix-like 的所有系统,都是以 "\n" 作为换行符。
注: 在比较旧的 Mac 系统上,是以 "\r" 作为换行符。
在 Windows 上都是以 "\r\n" 作为换行符。
就酱

在 GitHub 上使用 GnuPG

效果大概是这样:
screenshot

首先,创建一个 gpg key,这个比较简单,就略过了。
然后 key 的 id 是 2F6A12EF49B4426012129ED0CA3435EDDAEE3483,设置 git 签名公钥为 2F6A12EF49B4426012129ED0CA3435EDDAEE3483

$ git config --global user.signingkey 2F6A12EF49B4426012129ED0CA3435EDDAEE3483

导出 key 的公钥,并上传到GitHub服务器:

$ gpg --armor --export 2F6A12EF49B4426012129ED0CA3435EDDAEE3483
-----BEGIN PGP PUBLIC KEY BLOCK-----

mQENBFkYPJoBCAC9cHHySDMhfWoV6DpsLT6GQOV1F6T/5qqBxWWJ2Jdy1F1HRY7w
28tFHHdAA4qNC8aqQB33zWKWmm92Nr+aM7rvvY5Jza2Q3xANXrnZHi2ztSkPv0/j
rqnXH/E+5uLbQMMuJjwFWni/spgYbpBHBiFchh5m7nNZY4SqrSCPcFBhWbC4y6zC
vsQpnojzbzeY6ald6OsVw0dYC46DXzHqlqDhek0xVaoeYJU894n8vGkNShEFienI
7nozLZck1rjhSxBuKSELu3ZvOmMxYiu9PdrzxVvv3ZX0Tzdk/cM78rGtq0PXqrbQ
ICUcT9l3OVq9zbHS9dautHSo320wmF8R82BzABEBAAG0G0ppbmdKaW5nSGFjayA8
aUBrZXJuZWwubW9lPokBVAQTAQgAPhYhBC9qEu9JtEJgEhKe0Mo0Ne3a7jSDBQJZ
GDyaAhsDBQkDwmcABQsJCAcCBhUICQoLAgQWAgMBAh4BAheAAAoJEMo0Ne3a7jSD
U24H/A7M6UiNlbkyShFVXVl5eo2cj3KWbABVjaKEWAPlX9H6Nuzt4kv7qP4DWLd5
p20L/zap0NDpSvmTXUlEmzPy8P9lp9rlywNtK9DHp8vONPxEf1KXP+P3HWEAa8eU
KpGAp/G9y9kHh0+Yw4nqfQB4VsgLMq1a9sAq02g0oxn44Q4PLDa3BdDJAhKsC5Jt
gsrr07s8+3W7ahhbXxCQ0ROFgv6Z0erijmpmYy+d7hdvl22CzbGoY+DEpVFRpPXy
3pF+n01GE2CJrSnu4RFLp4KEtozlBqZ3CcoE0qruhm6AwAqVuOWdDdncQxykeE8q
5G7P1gKtslotF7Bz9YVH7EGNjCO5AQ0EWRg8mgEIAMf4ulkoT1wXp1kdTPSOsFzU
fEWmWIfqbtDXu8aE7u0GrqhMo6I9oopR6k9wGOmV6U0ttevS6xDUb7OBTkUW4PNy
2X6UQ4LtKZFwvCw3qnMCDQCI9R5Wjm5xzc9lzLHjV9tRX9tNA2G/YETYoNp2HMI0
wVif5fRwdTXrHF9EoKRhUgFdbJxdqEBMR0feyv9PZ2pGpYWsOgF2k5en6lmOuQCJ
rWnbFyzrp6cWIl880yrD+J9EedXivINcOb10HB3Kr/+q2qQ+h2BYgaUgVenNEbQR
F9cMylWZhdV3ZM+uoOQIJku/Vsdy+wkUK5kLONJvH1ZtDyTmHE0l7DYcJOaG4rkA
EQEAAYkBPAQYAQgAJhYhBC9qEu9JtEJgEhKe0Mo0Ne3a7jSDBQJZGDyaAhsMBQkD
wmcAAAoJEMo0Ne3a7jSDhswH/3E1UWS9Y31GxlJCeUXbJk819QydAkHTm3mUttYB
N8l1NdtbZESQgt/42ZknuZlZRPpsKOkP52nqdwOaoA+HKoc/VnlYVQqAEVEZkSZg
9wP6olRu0h4O181AMI9PTvoyIW830lj/urpW1vljNl1hNI/2raC4IG2M/v+/+3qb
BWuYEvCguzbOci4mkGpacGFeM8DywCr5ZZB1zSXTmUyOutl2BF9eebRjrEXrhy0+
rQ8Fo4X45VcC9bXvtQjevzWkEMhaviA93eXMvO1muanFy9ApOhzO74y688Rax5Jv
WlvGslgg4kO3byO5SvRG1y1FCjDbHwy1hO4wTX+fsDQ5q+w=
=zXH3
-----END PGP PUBLIC KEY BLOCK-----

添加 key 公钥到 GitHub 之后,在你的 GitHub repo 里提交一个 commit:

$ git commit -m "test" -S

发现多了一个 -S 参数,这个参数是 Signature 的缩写,意思大家应该懂得。
然后输入 git log --show-signature 可以看到有一个类似这样的文本: gpg: Good signature from "JingJingHack <i@kernel.moe>" [ultimate]
每次都需要加一个 -S 会发现很繁琐,可以设置git,让它自动签名。

$ git config commit.gpgsign true # 只对该项目有效
$ git config --global commit.gpgsign true # 全局(所有项目都使用GPG签名)

字节序笔记

先来简单的理解小端序和大端序。

大端序

大端序是字节序的一种,也是比较常用的一种。
Java 语言就是使用大端序来存储。
假设你有一个 int 型的变量,它的值为 23333,对应的十六进制是 0x5B25
在大端序中内存是这样存储的:

0x001 5B
0x002 25

数据的增长方向在右边,

小端序

再拿 23333 和 int 来做示例,在小端序中内存是这样存储的:

0x001 25
0x002 5B

它跟大端序是反向的,阅读顺序是从左到右,数据的增长方向也是右。

mc protocol

因为 mc 使用的是 Java,所以使用的是大端序,而我的环境是使用小端序的(x86架构cpu c++语言)。
看起来只要把小端序转成大端序就可以啦,至于字节序的转换嘛,boost 爸爸已经实现了相关库:

#include <boost/endian/conversion.hpp>
void test()
{
   int v1;
   int v2 = boost::endian::native_to_big<int>(v1); // 把本地使用的字节序转成大端序
}

C++11 中返回一个空list-initalizer

今天在看夏幻菊苣的NatsuLib中看到这么一句代码:

natThread::ResultType natThread::ThreadJob()
{
    return {};
}

这是一个什么意思呢,可以理解为:

natThread::ResultType natThread::ThreadJob()
{
    return {}; // It returns natThread::ResultType();
}

例子:

int testInt()
{
    return {}; // It returns 0
}
std::string testString()
{
    return {}; // It returns std::string();
}

参考

http://en.cppreference.com/w/cpp/language/list%20initialization
https://github.com/akemimadoka/NatsuLib/blob/master/NatsuLib/natMultiThread.cpp#L68