C++ - Type Erasure

Key points

继承中的多态:子类实现(implement)父类中定义的接口。

模板中的多态:不同的类遵守(conform to)相同的接口。

使用基于模板的多态的问题是caller也要是模板,即传染性。总的来说,有需要异质(heterogeneous)容器的需求;而一般的容器都要求元素是相同的类型(homogeneous)。

OO中的interface类比于template中的concept;OO中的interface和implement/instance类比于concept和model。

std::any是一个类(不是类模板),以type-safe的方式存is_copy_constructible类型的值。即只要类型conform to is_copy_constructible接口,它的值就能存在any对象里面。any擦除了任何is_copy_constructible类型的实际类型。

std::function是个类模板,它是一个function wrapper,可以存并调用任何CopyConstructibleCallable的target:function pointer,lambda expression,bind expression,function object/functor,pointer to member function(non-static/static,virtual/non-virtual),pointer to data member。function擦除了target的实际类型,而其模板参数表明了target应该conform to的函数原型。

尽管etl::delegate看上去和std::function很像,但是它没有使用类型擦除技术;是否有类型擦除,主要还是看它是存wrapper还是不是。

和CRTP的不同

Type Erasure实现了runtime polymorphism(但不依靠继承),CRTP(Curiously Recurring Template Pattern)实现了compile-time polymorphism(static dispatch或者policy-based design)。Type Erasure以性能换取弹性(trades performance for flexibility),CRTP以弹性换取性能(trades flexibility for performance),更强的type safety。

简单从表相上来看,Type Erasure是模板类继承自普通类,CRTP是普通类继承自模板类。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// Type Erasure

class Concept {
public:
virtual void interface() = 0;
};

template<typename Concrete>
class Model : public Concept {
Concrete* object; // hold the concrete object
public:
virtual void interface() override {
// dispatch to object->implementation()
}
};

class Concrete {
void implementation() {} // don't have to be virtual
};
1
2
3
4
5
6
7
8
9
10
// CRTP

template<typename Derived>
struct Base {
void interface() { static_cast<Derived*>(this)->implementation(); }
};

struct Derived : public Base<Derived> {
void implementation() {}
};

Examples

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
class SeeAndSay {
class AnimalConcept {
public:
virtual const char* see() const = 0;
virtual const char* say() const = 0;
};

template<typename T>
class AnimalModel : public AnimalConcept {
const T* m_animal;
public:
AnimalModel(const T* animal) : m_animal(animal) {}
const char* see() const { return m_animal->see(); }
const char* say() const { return m_animal->say(); }
};

vector<AnimalConcept*> m_animals;

public:
template<typename T>
void addAnimal(T* animal) {
m_animals.push_back(new AnimalModel(animal));
}

void pullTheString() {
for (auto animal : m_animals) {
cout << "The " << animal->see()
<< " says '" << animal->say()
<< "'!" << endl;
}
}
};

struct Cow {
const char* see() const { return "cow"; }
const char* say() const { return "moo"; }
};

struct Pig {
const char* see() const { return "pig"; }
const char* say() const { return "oink"; }
};

struct Dog {
const char* see() const { return "dog"; }
const char* say() const { return "woof"; }
};

int main() {
SeeAndSay seeAndSay;
seeAndSay.addAnimal(new Cow);
seeAndSay.addAnimal(new Pig);
seeAndSay.addAnimal(new Dog);
seeAndSay.pullTheString();

return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
class Object {
struct ObjectConcept {
virtual ~ObjectConcept() = default;
};

template<typename T>
struct ObjectModel : ObjectConcept {
ObjectModel(const T& t) : object(t) {}
virtual ~ObjectModel() = default;
private:
T object;
};

shared_ptr<ObjectConcept> object;

public:
template<typename T>
Object(const T& t) : object(make_shared<ObjectModel<T>>(t)) {}
};

struct Foo {};
struct Bar {};

int main() {
vector<Object> objects;

objects.push_back(Object(1));
objects.push_back(Object(Foo()));
objects.push_back(Object(Bar()));

return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
class Greeter {
public:
template<class T>
Greeter(T data) : self_(make_shared<Model<T>>(data)) {}

void greet(const string& name) const {
self_->greet(name);
}

private:
struct Concept {
virtual ~Concept() = default;
virtual void greet(const string&) const = 0;
};

template<class T>
class Model : public Concept {
public:
Model(T data) : data_(data) {}

virtual void greet(const string& name) const override {
data_.greet(name);
}

private:
T data_;
};

shared_ptr<const Concept> self_;
};

struct English {
void greet(const string& name) const {
cout << "Good day " << name << ". How are you?\n";
}
};

struct French {
void greet(const string& name) const {
cout << "Bonjour " << name << ". Comment ca va?\n";
}
};

void greet_tom(const Greeter& g) {
g.greet("Tom");
}

int main() {
greet_tom(English());
greet_tom(French());

return 0;
}

References

Technology Evolution

IT Evolution

  • Centralized Mainframe
  • Personal Computing
  • Client Server
  • Enterprise Computing
  • Cloud Computing

Software Development

  • Pioneering Days
  • High-level Languages
  • Personal Computer Revolution
  • Internet Age
  • Rise of Mobile and Apps
  • Cloud Computing and AI

ABCDE

  • AI
    • Machine Learning
    • Deep Learning
    • Generative model
    • Pre-trained model
  • Blockchain
  • Cloud Computing
    • Distributed System
    • Cluster Computing
    • Grid Computing
    • Virtualization
    • Web2
      • Service Orientation
        • IaaS
        • PaaS
        • SaaS
        • XaaS
      • Utility Computing
    • Cloud Native
      • Microservice
      • Container
      • Orchestration
  • Data
    • Database
    • SQL
    • Mining
    • Warehouse
    • Stream
    • In-memory
    • Big Data
    • NoSQL
  • Experience

Topics

  • OS
  • Web
  • Mobile OS and Internet
  • Cloud Service
  • IoT / Hardware
  • Embedded System
    • MCU
    • SoC

Windows激活本地admin

传统的组策略(group policy)

1
gpupdate /force

dsregcmd: diagnose and manage device registration with Microsoft Entra ID (formerly Azure AD)

PRT: Primary Refresh Token

1
2
3
dsregcmd /status

dsregcmd /refreshprttoken

检查账号信息

1
2
3
whoami /groups

whoami /priv

常规操作:重启;重新登录;重连网络;重启windows explorer。

What's difficult?

在中文里有几层意思

difficult

它表示事情不容易完成或者不知道怎么做。

hard

它表示需要很大努力。

复杂

complex表示结构性复杂;complicated表示难以理解或处理。More is different。

反义词

与“难”相对的就是easy或者simple

能量守恒

Effort守恒

  • No pain, no gain
  • Hard work pays off
  • No free lunch

问题守恒

  • Problems never disappear, they just change form.
  • Solving one problem often creates another.
  • There’s no end to problems, only transformations.

矛盾总是存在的,变化的。

生成容器镜像的几种方式

commit

commit可能是最简单直白的方法。

  1. 运行一个容器
1
2
3
4
5
6
7
8
$ docker run \
-it \
-u 1000 \
-h foo-host \
-v foo-tmp-volume:/workspaces/tmp \
-w /home/ubuntu \
--name foo-ubuntu \
myubuntu:latest
  1. commit从容器创建新镜像
1
2
3
4
5
6
$ docker commit \
-a "Bill Dong" \
-c "CMD [ \"/bin/bash\" ]" \
-c "LABEL foo=bar" \
-m "foo-ubuntu-image init" \
foo-ubuntu foo-ubuntu-image:latest

save / load

save将镜像保存至tarball,包括元数据;load将tarball装载成镜像。

export / import

export将容器的文件系统导出至tarball,不包括元数据;import将tarball导入成文件系统镜像。

注意:该操作可以将多层文件系统变成一层;导入时可能会丢失CMD之类的信息,使用-c选项设置。

build

build是推荐的方法。

  1. 写一个Dockerfile
1
2
# FROM scratch
FROM myubuntu:latest
  1. 构建镜像
1
$ docker build .

git:如何更新main分支

fetch - Download objects and refs from another repository

1
git fetch --prune --all
1
2
git switch main
git fetch [origin] [main]
1
git fetch origin main:main

pull - Fetch from and integrate with another repository or a local branch

1
2
3
git switch main
git pull [origin] [main]
git pull --rebase

merge - Join two or more development histories together

1
2
git switch main
git merge origin/main

rebase - Reapply commits on top of another base tip

1
2
git switch main
git rebase origin/main
1
git rebase origin/main main
1
2
3
git rebase --onto <newbase> <upstream> <branch>
# <newbase> default: <upstream>
# <branch> default: HEAD

branch - List, create, or delete branches

1
git branch main

switch - Switch branches

1
git switch -c main

restore - Restore working tree files

checkout - Switch branches or restore working tree files

1
git checkout main

reset - Reset current HEAD to the specified state

1
2
git switch main
git reset origin/main

Basic Settings for Linux

apt

  • apt-get update
  • git (config)
  • vim
  • tree
  • mlocate (updatedb)
1
2
sudo apt-get update
sudo apt-get install build-essential git vim tree plocate

bash

  • bashmy
  • bashrc
1
git clone https://github.com/forestdbin/code-snippet.git

vim

  • update-alternatives
  • vimrc
1
sudo update-alternatives --config editor

sudo

1
2
# visudo
%sudo ALL=(ALL:ALL) NOPASSWD:ALL

vmtools

道法术器

道法术器 is a concept rooted in Chinese philosophy, particularly in Daoism and strategic thinking. It represents four key elements:

The fundamental principle or way, often referring to the natural order or ultimate truth.

The rules, methods, or laws that guide actions and governance.

The techniques or strategies used to achieve goals.

The tools or tangible resources that support execution.

This framework is often used in leadership, governance, and personal development, emphasizing the importance of aligning one’s actions with universal principles while utilizing effective methods, strategies, and tools.

Would you like to explore how this applies to a specific area, like bussiness or personal growth? :)

Docker Registry

Mirror the Docker Hub library

重新打标签

1
2
docker pull <your-registry-mirror>[:<port>]/library/busybox
docker tag <your-registry-mirror>[:<port>]/library/busybox:latest busybox:latest

运行一个Registry

Registry image

1
2
3
4
5
$ docker pull registry
$ docker run -d -p 5000:5000 --restart always --name registry registry:2
$ docker pull ubuntu
$ docker tag ubuntu localhost:5000/ubuntu
$ docker push localhost:5000/ubuntu

pull-through cache

1
2
3
# /etc/docker/registry/config.yml
proxy:
remoteurl: https://registry-1.docker.io

配置Docker daemon

1
2
3
4
5
6
7
# /etc/docker/daemon.json
{
"registry-mirrors": ["https://<my-docker-mirror-host>"]
}

# sudo systemctl daemon-reload
# sudo systemctl restart docker

镜像加速

镜像加速服务状态监控

DaoCloud

1panel

渡渡鸟