Question: I am very confused about the const version and non-const version member function like below:

```
value_type& top() { return this.item }
const value_type& top() const { return this.item }

```

What is the difference between these two functions? In what situation would they be used?

Answer: 
If you have 

```
class Foo
{
    value_type& top() { return this.item }
    const value_type& top() const { return this.item }
}

```

If you have

```
Foo foo;
const Foo cfoo;

```

The return types when you call `top()` are as follows:

```
value_type& bar = foo.top();
const value_type& cbar = cfoo.top();

```

In other words - if you have a constant instance of your class, the const version of the function is chosen as the overload to call.

The reason for this (in this particular case) is so that you can give out references to members (like `item` in this case) from a const instance of a class, and ensure that they too are const - thus unmodifiable and therefore preserving the const-ness of the instance they came from.
`value_type& top() { return this.item; }` ensures that either the calling object's data members can be modified or the return value can be.

`value_type& top() const { return this.item; }` ensures that the calling object's data members can't be modified, but the return value can be. So, for example, if I perform `value_type item_of_x = x.top();`, `item_of_x` can be modified but `x` cannot. Otherwise, a compiler error occurs (such as having the code `this.item = someValue;` inside of the function body).

`const value_type& top() { return this.item; }` ensures that the calling object's data members are allowed to be modified, but the return value cannot be. It's the opposite of what is discussed above: if I perform `const value_type item_of_x = x.top();`, `item_of_x` can't be modified but `x` can. **NOTE** `value_type item_of_x = x.top();` still allows for modification of `item_of_x`, as `item_of_x` is now non-const.

`const value_type& top() const { return this.item; }` ensures that neither the calling object's data members can be modified nor the return value can be.