Type erasure is a technique that allows you to store objects of different types in a container or pass them around as function parameters without knowing their specific type at compile time. One way to achieve type erasure in C++ is by using void*
pointers. Here’s an example that demonstrates type erasure using void*
:
#include <iostream>
// Abstract base class for any type that can be erased
class Erasable {
public:
virtual void print() const = 0;
};
// Concrete implementation of Erasable for integers
class Integer : public Erasable {
private:
int value;
public:
Integer(int val) : value(val) {}
void print() const override {
std::cout << "Integer: " << value << std::endl;
}
};
// Concrete implementation of Erasable for strings
class String : public Erasable {
private:
std::string value;
public:
String(const std::string& val) : value(val) {}
void print() const override {
std::cout << "String: " << value << std::endl;
}
};
int main() {
// Create a vector of void* pointers to store objects of different types
std::vector<void*> objects;
// Create instances of Integer and String
Integer integer(42);
String str("Hello, world!");
// Store the objects in the vector as void* pointers
objects.push_back(static_cast<void*>(&integer));
objects.push_back(static_cast<void*>(&str));
// Retrieve the objects from the vector and call their print() function
for (void* obj : objects) {
Erasable* erasable = static_cast<Erasable*>(obj);
erasable->print();
}
return 0;
}
In this example, we define an abstract base class called Erasable
that declares a pure virtual function print()
. We then create two concrete implementations of Erasable
: Integer
and String
. Both classes override the print()
function to provide their specific implementation.
In the main()
function, we create a vector of void*
pointers called objects
. We create instances of Integer
and String
and store them in the objects
vector as void*
pointers using static_cast
. Later, we retrieve the objects from the vector and call their print()
function by first casting the void*
pointers back to Erasable*
.
This allows us to store objects of different types in the same container and invoke polymorphic behavior through the Erasable
interface, achieving type erasure using void*
pointers.