# Templates

Compile-time monomorphization: each unique type combination produces a separate concrete implementation.

## Template Structs

```cpp
template<typename T>
struct Pair {
    T first;
    T second;
    Pair(T a, T b) { first = a; second = b; }
    T sum() { return first + second; }
}

Pair<int32> p = Pair<int32>(10, 20);
println(p.sum());  // 30

Pair<float64> fp = Pair<float64>(1.5, 2.5);
println(fp.sum());  // 4.0
```

## Template Functions

```cpp
template<typename T>
T max_val(T a, T b) {
    if (a > b) return a;
    return b;
}

int32 m = max_val<int32>(10, 20);  // 20
```

## Template with Reference Parameters

```cpp
template<typename T>
void swap_vals(T& a, T& b) {
    T temp = a;
    a = b;
    b = temp;
}

int32 x = 10;
int32 y = 20;
swap_vals<int32>(x, y);  // x=20, y=10
```

## Nested Templates

Template functions can take template-typed args:

```cpp
template<typename T>
struct Box {
    T val;
    Box(T v) { val = v; }
    T get() { return val; }
}

template<typename T>
T unwrap(Box<T> b) {
    return b.get();
}

Box<int32> b = Box<int32>(42);
int32 v = unwrap<int32>(b);  // 42
```

Type args themselves can be template instantiations — `Pair<Pair<int64>>`, `Box<Box<Box<int64>>>`, etc. The closing `>>` parses without spacing in both type position and ctor-call position.

## Templated Base Classes

A class can inherit from a template instantiation:

```cpp
template<typename T> class Box {
    T value;
    Box(T v) { value = v; }
    T get() { return value; }
}

class IntBox : Box<int64> {
    IntBox(int64 v) : Box<int64>(v) {}
}

int64 main() {
    IntBox* b = new IntBox(42);
    int64 r = b->get();    // inherited from Box<int64>
    delete b;
    return r;
}
```

The init-list syntax `: Box<int64>(v)` invokes the instantiated base ctor. Override syntax in the derived class works as usual:

```cpp
class Special : Box<int64> {
    Special(int64 v) : Box<int64>(v) {}
    int64 get() override { return value * 100; }
}
```

## Nested-Array Init Lists

For typed arrays of arrays (or arrays of structs), brace-init lists nest naturally:

```cpp
int64[][] grid = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
int64 v = grid.get(1).get(0);   // 4

int64[][][] cube = {{{1, 2}, {3, 4}}, {{5, 6}, {7, 8}}};
int64 c = cube.get(1).get(0).get(1);   // 6

struct Point { int64 x; int64 y; }
Point[] pts = {Point(1, 2), Point(3, 4), Point(5, 6)};
Point p = pts.get(2);  // Point(5, 6)
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://enma-1.gitbook.io/enma/language-guide/templates.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
