The `Ref<T>` and `RefMut<T>` are both the simplest classes in [[Crab]], both are simply very thin wrappers over a [[Const]] [[../../../../02 Areas/Computer Science/Me Bitching about C++/Reference|Reference]] (`const T&`) or a [[../../../../02 Areas/Computer Science/Me Bitching about C++/Mutation|Mutable]] [[../../../../02 Areas/Computer Science/Me Bitching about C++/Reference|Reference]] (`T&`) respectively.
The only reason why you would ever want to use one of these over an actual `const T&`/`T&` is in contexts where [[C++]] doesn't allow you to put one, but you still want to encode the idea that the value is never [[../../../../02 Areas/Computer Science/Me Bitching about C++/Null]].
The only time this really happens is if you want to use a [[../../../../02 Areas/Computer Science/Me Bitching about C++/Reference|Reference]] [[../../../../02 Areas/Computer Science/Me Bitching about C++/Type|Type]] inside of some [[../../../02 Areas/Me Bitching about C++/Templates|Templated Type]], as for all [[Standard Template Library|STL]] types you can't use a reference.
>[!question]- What is `Vec<T>`?
> In all of these examples, whenever you see `Vec<T>`, that is just the type alias for `std::vector<T>` provided by [[Crab]].
>[!error] When you can't use [[../../../../02 Areas/Computer Science/Me Bitching about C++/Reference|References]]
>
>```cpp
// these all compile & all methods work!
Vec<i32*> ptr_vec0; // vector of pointers to ints (possibly null)
Vec<const i32*> ptr_vec1; // vector of pointers to immutable ints (possibly null)
std::unordered_map<String, i32*> ptr_map; // map with key-value pairs from a String to a pointer to a int (possibly null)
Option<i32*> ptr_opt; // Optional pointer to an int (the pointer could still be null) (possibly null)
>
// these will not compile
Vec<i32&> ref_vec0; // Vector of references to ints
Vec<const i32&> ref_vec1; // Vector of references to immutable ints
std::unordered_map<String, i32&> ref_map; // map with key-value pairs from a String to a reference to an int
Option<i32&> ref_opt; // Optional reference to an int
>[!success] Version that works with [[Crab]]
>```cpp
>Vec<RefMut<i32>> ref_vec0;
>Vec<Ref<i32>> ref_vec1;
>std::unordered_map<String, RefMut<i32>> ref_map;
>Option<RefMut<i32>> ref_opt;
>```
</bruh>
In these cases, you could just use the [[Pointer]] variants - but my problem with that is that reading the variable's types then gives it a different interpretation.
Having some variable $r$ of type `i32&` means that $r$ is a reference to some other `i32`, but having another variable $p$ of type `i32*` means that $p$ points to some other `i32` *or* is [[../../../../02 Areas/Computer Science/Me Bitching about C++/Null|Null]] (invalid).
In a similar vain, being able to use a [[../../../../02 Areas/Computer Science/Me Bitching about C++/Reference]] [[../../../../02 Areas/Computer Science/Me Bitching about C++/Type]] instead of a raw [[Pointer]] [[../../../../02 Areas/Computer Science/Me Bitching about C++/Type]] for some variable $c$, *eg.* from a `Vec<i32*>` into `Vec<RefMut<i32>>`, alters the meaning from a vector of *possible* locations to an `i32`, to a vector of locations to an `i32`.
>[!example]
```cpp
struct Entity { /* ... */ };
struct Game { // ...
// An entity in this should never be null.
Vec<RefMut<Entity>> entities{};
};
```
>[!warning]- Note on the use of raw pointers
>I would still recommend against a raw pointer in most cases even if you wanted the idea of the data being able to be invalid,
>
> >[!example]-
> >*ex.* An entity list similar to the one used in CS230 where the entities in the list could be invalid, meaning that when you delete an entity you dont have to move everything to fill in the `null` spot.
>
> In this case, I would instead really recommend using an [[Option<T>]] with [[Ref<T> + RefMut<T>]], such as `Option<RefMut<Entity>>`, to make the possibility of being an invalid state more explicit - as it is *extremely* easy to bypass (or more likely, forget) a [[../../../../02 Areas/Computer Science/Me Bitching about C++/Null]] check.