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: 
In short, they're used to add 'const correctness' to your program.

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

```

This is used to provide mutable access to `item`. It is used so you can modify the element in the container. 

For example:

```
c.top().set_property(5);  // OK - sets a property of 'item'
cout << c.top().get_property();  // OK - gets a property of 'item'

```

One common example for this pattern is returning mutable access to an element with `vector::operator[int index]`.

```
std::vector<int> v(5);
v[0] = 1;  // Returns operator[] returns int&.

```

On the other hand:

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

```

This is used to provide `const` access to `item`. It's more restrictive than the previous version - but it has one advantage - you can call it on a const object.

```
void Foo(const Container &c) {
   c.top();  // Since 'c' is const, you cannot modify it... so the const top is called.
   c.top().set_property(5);  // compile error can't modify const 'item'.
   c.top().get_property();   // OK, const access on 'item'. 
}

```

To follow the vector example:

```
const std::vector<int> v(5, 2);
v[0] = 5;  // compile error, can't mutate a const vector.
std::cout << v[1];  // OK, const access to the vector.

```
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.