capypad
0 Tage Serie
cpp / expert
Snippet

Type-Erasure mit polymorphen Wrappern

Type-Erasure ist eine Technik zum Speichern von Objekten verschiedener Typen, die eine bestimmte Schnittstelle (wie 'render()') bereitstellen, ohne dass diese von einer gemeinsamen Basisklasse erben müssen. So sind std::function und std::any implementiert.

snippet.cpp
cpp
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
#include <iostream>
#include <memory>
#include <vector>
 
class Drawable {
struct Concept {
virtual ~Concept() = default;
virtual void draw() const = 0;
};
template <typename T> struct Model final : Concept {
Model(T x) : data(std::move(x)) {}
void draw() const override { data.render(); }
T data;
};
std::unique_ptr<Concept> self;
public:
template <typename T> Drawable(T x) : self(std::make_unique<Model<T>>(std::move(x))) {}
void draw() const { self->draw(); }
};
 
struct Circle { void render() const { std::cout << "Circle\n"; } };
 
int main() {
std::vector<Drawable> items { Circle{} };
items[0].draw();
}
Erklärung
1
struct Concept { ... virtual void draw() ... };
Eine interne abstrakte Basisklasse, die die erforderliche Schnittstelle definiert.
2
template <typename T> struct Model : Concept { ... };
Ein templated Wrapper, der den generischen draw()-Aufruf auf die spezifische render()-Methode von Typ T mappt.