On Monday, 1 September 2025 at 22:45:58 UTC, Steven Schveighoffer wrote:

...
And also note that structs already support encapsulation. They just don't do inheritance/polymorphism.


True, but 'structs + templates' is a usable pattern for 'static polymorphism' - the effect of which, is to allow interchangeable objects, but without having to use inheritance or virtual method tables.

In this example below, any type passed to the templated utility function 'calculateTotalArea', must have a callable area() method.

The templated utility function is actually very fast, because the compiler hardcodes the exact function call (rect.area() or sq.area()). That is, it creates a completely new function optimized specifically for the data type T.

However, there is a limitation. You can only use the templated utility function to process an array of Rectangles, and then again, to process an array of Squares.

Of course, with runtime polymorphism you could make a single, unified call - but then you have some overhead associated with the need to make complex decision-making during runtime execution.

If you're process a large collection of simple shape objects in a tight loop, then the performance of static polymorphism will likey win - primarly because you reduce the likelihoood of branch prediction failures, and having the data (value types) laid out contiguously in memory is ideal to fully utilize the various CPU cache levels.


// -------------------------------------

module mymodule;
@safe:
private:

import std.stdio;

struct Rectangle
{
    int width;
    int height;
    int area() const { return width * height; }
}

struct Square
{
    int side;
    int area() const { return side * side; }
}

int calculateTotalArea(T)(T[] shapes)
{
    int total = 0;
    foreach (s; shapes)
    {

        total += s.area;
    }
    return total;
}

void main()
{
    writeln("--- Shape Calculations (D) - Templates (Final) ---");

    Rectangle[] rects = [
        Rectangle(10, 5),
        Rectangle(20, 3)
    ];
    int rectsArea = calculateTotalArea(rects);
    writeln("\nTotal Area of Rectangles: ", rectsArea);

    Square[] squares = [
        Square(7),
        Square(12)
    ];
    int squaresArea = calculateTotalArea(squares);
    writeln("Total Area of Squares: ", squaresArea);
}

// -------------------------------------

Reply via email to