-1

I am trying to write a print function which prints in reverse order elements of linked list. It works only when I declare the function non-const with const it does not work and throw below error.

cannot convert 'this' pointer from 'const slist<int>' to 'slist<int> &'

I saw few SO post with regard to it like below Call a non-const member function from a const member function and the associated post with that link but I am unable to understand it. If someone can help me understand it

My code : Gives error : cannot convert 'this' pointer from 'const slist<int>' to 'slist<int> &'

void slist<T>::print_with_recursion() const
{
    node<T>* head = _first;
    print_reverse(head);

}

void slist<T>::print_reverse(node<T>* head)
{
    if (head) 
    {
        print_reverse(head->_next);
        cout << head->_data << endl;
    }
}

if I remove const I dont get any error. Also if there is better way to implement printing linked list in reverse order give function definition print_with_recursion() const please do suggest.

Community
  • 1
  • 1
thedreamer
  • 319
  • 1
  • 5
  • 13
  • You can't call a non-const (`print_reverse`) member function from a const member function. – T.C. Nov 03 '15 at 20:26
  • 3
    Is it any reason why the `print_reverse` is non-const? – Piotr Siupa Nov 03 '15 at 20:29
  • Thank u - however the problem statement which has been given is to implement print function for given definition print_with_recursion() const, what would be best way to achieve it in that case ? I just got it working as a workaround – thedreamer Nov 03 '15 at 20:31
  • *"but I am unable to understand it"* - That's about as helpful as "it doesn't work". **What exactly** do you not understand? – Christian Hackl Nov 03 '15 at 20:34
  • @NO_NAME: I think I got it - if I declare print_reverse as const it works fine and the point as well const function can have only const function inside it .. thanks :) – thedreamer Nov 03 '15 at 20:34
  • @ChristianHackl - What I did not understand clearly before the post was we should call const function only inside defined const function. Now you can say why I didnt get it at first go by reading post - I am clueless too :) – thedreamer Nov 03 '15 at 20:45

3 Answers3

3

Your function is const but calling a non-const member function (print_reverse) which is not allowed.

There's no reason why any of this shouldn't be fully const as you don't need to change any of the data of the object. Try instead:

void slist<T>::print_with_recursion() const
{
    const node<T>* head = _first;
    print_reverse(head);
}

void slist<T>::print_reverse(const node<T>* head) const
{
    if (head) 
    {
        print_reverse(head->_next);
        cout << head->_data << endl;
    }
}
Component 10
  • 10,247
  • 7
  • 47
  • 64
2

if I remove const I dont get any error

That is the best solution. You should make it a habit of making any function that does not need to change its state a const member function.

Coming to your particular problem, you can make print_reverse a non-member function

template <typename T>
void print_reverse(node<T>* head)
{
    if (head) 
    {
        print_reverse(head->_next);
        cout << head->_data << endl;
    }
}

Then, there is no need to worry about const-ness of the function.

I would suggest the additional change of making the std::ostream an argument to the function.

template <typename T>
void print_reverse(node<T>* head,
                   std::ostream& out)
{
    if (head) 
    {
        print_reverse(head->_next, out);
        out << head->_data << std::endl;
    }
}
R Sahu
  • 204,454
  • 14
  • 159
  • 270
  • Thank u - however the problem statement which has been given is to implement print function for given definition print_with_recursion() const, what would be best way to achieve it in that case ? – thedreamer Nov 03 '15 at 20:31
  • @thedreamer, I would make `print_reverse` non-member function, then. – R Sahu Nov 03 '15 at 20:33
0

The issue here is that class member functions have a hidden parameter of that class type. So

void slist<T>::print_with_recursion() const

is actually

void slist<T>::print_with_recursion(const slist<T> *) const

and

void slist<T>::print_reverse(node<T>* head)

is

void slist<T>::print_reverse(slist<T> *, node<T>* head)

So when you are in print_with_recursion() the this pointer is a const slist<T> * and when you call print_reverse() you try to pass that const pointer to a function expecting a non const pointer.

You can fix this by making print_reverse() const as then it will take a const slist<T> * instead of a slist<T> *. It is also a good idea to mark functions that will not change the state of the object as const.

NathanOliver
  • 171,901
  • 28
  • 288
  • 402