Question: STL containers have a `reference` and `const_reference` `typedef`, which, in many cases I've seen (containers of `bool` being the only exceptions I can think of), could be trivially defined as

```
typedef value_type& reference;
typedef const value_type& const_reference;

```

What exactly, however, are the *semantics* of these types? 

From what I understand, they are supposed to "behave like references to the value type", but what exactly does that mean?

MSDN says that `reference` is:

> 
> A type that provides a reference to an element stored in a vector.
> 
> 
> 

But what does this mean, exactly? Do they need to overload specific operators, or have a specific behavior? If so, what is the required behavior?

Answer: 
Taken out of the standard:

![enter image description here](https://i.stack.imgur.com/oBERF.png)

It also defines `reference` as a typedef of `value_type&` which is a typedef of `T`

(New answer as previous one was different focus)
What you're asking is "Can I always dereference a reference? And yes, you can. That means dereferenced `reference` can do everything dereferenced `value_type&` can do which is everything `value_type` can do. If that makes sense to you. 

---

You can't overload operators on typedefs. typedefs have the same behavior as the type they are assigned to. The reason they are typedef'd is to make them less cumbersome and provide a common "interface"

The reason `reference` exists is to prevent things like this:

```
template<typename T>
struct foo {
  T& bar();

  typedef T& reference;
  reference baz();
}

foo<int> x;
foo<int>::T& y = x.bar(); // error! returns a T& but I can't create one!
foo<int>::reference z = x.baz(); // ok! 

```

It also makes a cleaner interface and allows use of SFINAE:

```
template<typename T>
typename T::reference second(T::reference& t) { return t.at(1); };

template<typename T>
T& second(T& t) { return t[1]; };

std::vector v(10);
foo f(10); // type with [] overloaded but no reference typedef
second(x) = 5; // calls first def
second(f) = 3; // calls second def

```