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: 
The const-qualified member function will be called if the member function is called on an object that is const-qualified.

The non-const-qualified member function will be called if the member function is called on an object that is not const-qualified.

For example:

```
MyStack s;
s.top(); // calls non-const member function

const MyStack t;
t.top(); // calls const member function

```

Note that the same rules apply when calling a member function on a reference to an object or through a pointer to an object: if the pointer or reference is to a const object, the const member function will be called; otherwise the non-const member function will be called.
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.