Fork me on GitHub

C++ Virtual Table

概述

为了实现 C++ 的多态,C++ 使用了一种 动态绑定 的技术。实现 动态绑定 的方法有很多种,但是很多编译器都是用了类似的方案:虚表。本文介绍如何通过 虚表 来实现 动态绑定

注意:虚表 本身并不是 C++ 的标准,它是编译器实现 动态绑定 的一种方式。

虚表

什么是虚表

虚表(Virtual Table) 是一个 指针数组,里面存储的是 函数指针,指向 虚函数

C++ Parameter Pack

可变参数函数模板通常是递归的。第一步调用处理包中的第一个实参,然后用剩余的实参调用自身。为了终止递归,我们还需要定义一个非可变参数的函数模板:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// template specialization
template <typename T>
void print(const T &t) {
std::cout << t;
}

// 包中除了最后一个元素的输出会调用上面的 `特化模板`,之外的其他元素都会调用这个版本的 print
template <typename T, typename...Args>
void print(const T &t, const Args&...rest) {
std::cout << t << " "; // 打印第一个实参
print(rest...); // 递归调用,打印其他实参
}

int main() {
print("string1", 2, 3.14f, "string2", 42);
std::cout << endl;
return 0;
}

Reference

typedef vs using in C++

Declaring new aliases

There are two ways of declaring new type aliases in modern C++:

  • typedef
  • using

注意:两者都没有 create 新的 type,只是一个原来的 type 的一个 alias.

typedef

The first and traditional one is with the typedef keyword:

C++ template

Definition

C++ 提供的一种抽象机制:允许我们编写一段 通用 的逻辑,来处理 任意类型 的变量。

这是 继承机制 以外的另一种抽象机制,极大地提升了代码的可复用性。

注意:模板定义本身不参与编译,而是编译器根据模板的用户使用模板时提供的类型参数生成代码,再进行编译,这一过程被称为模板实例化。用户提供不同的类型参数,就会实例化出不同的代码。

Category

C++ template 可以分为 2 个类别:

*_cast in C++

static_cast

static_cast 的主要应用场景为:

  • 用于基本数据类型之间的转换。但是由于数值范围的不同,需要用户保证转换的安全性。
  • 用于类指针/引用的上/下行转换。这种转换是在编译期完成的,如果无法完成转换,在编译的时候会报错。

其中对于类指针/引用的上/下行转换:

  • 用于上行转换的时候是安全的。
  • 用于下行转换的时候是不安全的,因为它不会做 run time 的类型检查。

这里对安全的定义,可以见下面和 dynamic_cast 对比的部分。

NOTES

基于生成对抗网络的网页显著度图预测

  • 使用 GAN(生成对抗网络)生成给定网页的显著度图,从而预测网页的哪些区域更会受到用户的关注。

  • 把网页快照和显著度图当作不同域别的图像,并使用 GAN 进行转换。设计多种不同结构的网络模型,加入自注意力机制与谱归一化,引入网页特征用于指导显著度图的生成,同时试用多种损失函数,并使用 TTUR 的方式对网络进行训练。

  • 使用的网络结构:

    • resnet

    • u-net

NLP

Skip-gram-Naive-Softmax

  • one-hot 缺陷

    • 维度爆炸

    • 不能表达语义关系:计算机,电脑

Word2Vec

  • 分为 CBOWSkip-gram,两种都是 predictive 的模型。

Reinforcement Learning

Markov Decision Processes (MDP)

  • 马尔科夫决策过程是强化学习的理论基础。不管我们是将强化学习应用于五子棋游戏、星际争霸还是机器人行走,我们都假设背后存在了一个马尔科夫决策过程。只不过有的时候我们知道马尔科夫决策过程所有信息(状态集合,动作集合,转移概率和奖励),有的时候我们只知道部分信息(状态集合和动作集合),还有些时候马尔科夫决策过程的信息太大无法全部存储 (比如围棋的状态集合总数为 319×19 )。强化学习算法按照上述不同情况可以分为两种: 基于模型 (Model-based) 和非基于模型 (Model-free)。基于模型的强化学习算法是知道并可以存储所有马尔科夫决策过程信息,非基于模型的强化学习算法则需要自己探索未知的马尔科夫过程。[3]

  • Reinforcement Learning 与 其他的 Machine Learning 的区别 马尔科夫决策过程(Markov Decision Processes)

    • 非监督的:我们通常只得到 reward signal。每次系统的 action 只能得到代表这次行为的好坏的标量,比如是 10 points,但是我们不知道他的最好的值是多少。