Skip to content
Author: ytianle

Heterogeneous Array⚓︎

Let's think about a case where we want to create an array ~that can store different types of objects~.

Introduction⚓︎

Traditional C++ uses tagged unions to create arrays capable of holding different types. However, they are not type-safe and can lead to undefined behavior. Since version C++17, C++ has constructs like std::variant to create arrays that can hold different types.

#include <vector>

union Variant {
    int i;
    double d;
    char c;
};
std::vector<Variant> heterogeneousArray = { 1, 3.14, 'a' };
#include <variant>
#include <vector>

std::vector<std::variant<int, std::string, double>> heterogeneousArray = { 1, "text", 3.14 };

DIY Heterogeneous Array⚓︎

DIY Heterogeneous Array
using System;
using System.Collections.Generic;
// We will use top-level statements for simplicity program-main style.

interface IShape { void Draw(); }
class Circle : IShape { public void Draw() => Console.WriteLine("Drawing a Circle."); }
class Rectangle : IShape { public void Draw() => Console.WriteLine("Drawing a Rectangle."); }

var shapes = new List<IShape> { new Circle(), new Rectangle() };
foreach (var s in shapes) s.Draw();
#include <iostream>
#include <vector>
#include <memory>

struct IShape { virtual void draw() const = 0; virtual ~IShape() = default; };
struct Circle : IShape { void draw() const override { std::cout << "Circle\n"; } };
struct Rectangle : IShape { void draw() const override { std::cout << "Rectangle\n"; } };

int main() {
    std::vector<std::shared_ptr<IShape>> shapes{
        std::make_shared<Circle>(),
        std::make_shared<Rectangle>()
    };
    for (const auto& s : shapes) s->draw();
}