Type erasure by void*

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.

Leave a Reply

Your email address will not be published. Required fields are marked *