Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ invalid conversion from ‘const type* const’ to ‘type*’

Tags:

c++

qt

I have a very silly question (I think). Its been long time not coding in C++, but I can't figure out this problem. I have this class:

#include <QList>
class Node {
private:
    QList<Node*> _adjacent;
public:
    Node();
    bool isConnectedTo(Node* n) const;
};

and this implementation for isConnectedTo():

bool Node::isConnectedTo(Node* n) const{
    return _adjacent.contains(n) && n->_adjacent.contains(this);
}

and I get the following error in the return line:

Node.cpp: In member function ‘const bool Node::isConnectedTo(Node*) const’:
Node.cpp:25:60: error: invalid conversion from ‘const Node* const’ to ‘Node*’ [-fpermissive]
In file included from /usr/include/qt5/QtCore/QList:1:0,
                 from Node.hpp:5,
                 from Node.cpp:1:
/usr/include/qt5/QtCore/qlist.h:913:27: error:   initializing argument 1 of ‘bool QList<T>::contains(const T&) const [with T = Node*]’ [-fpermissive]

I think that, since the method is constant, then this is of type const Node* const here. By reading th Qt doc, I see that QList::contains has the type bool QList::contains(const T & value) const so it should be ok, right? I mean, it takes a const Node*, and a const Node* constis a special case of that, so... By removing the const at the end of the siganture, it compiles...

Thanks!

like image 581
excalibur1491 Avatar asked Apr 03 '14 12:04

excalibur1491


2 Answers

Problem is here:

n->_adjacent.contains(this)

Since contains assumes that it will get Node* const and this is type of const Node*. Adding const is not a problem but removing is a problem. So try const_cast like this:

n->_adjacent.contains(const_cast<Node* const>(this))
like image 149
Marek R Avatar answered Nov 18 '22 12:11

Marek R


Inside your "isConnectedTo" function "this pointer" is a const Node * const pointer which means that "this" cant be used to change the contents of the Node object that it refers to.

In your call "n->_adjacent.contains(this)" you are passing "this" pointer to a function which has constant reference parameter (const T& ref where T is Node*). const T& ref where T is Node* means ref is Node* const& i.e a constant reference to a pointer. The constant here refers to the pointer and means that the reference cant be used to alter the pointer. But this does not mean that the reference cant be used to change the object (Node) that the pointer points to. So nothing can stop us from doing something like (*ref).call_to_non_const_function_in_Node.

But "this" pointer in your case points to a constant Node objject. That is why this code doesn't compile. It would have compiled if the parameter were a constant Node* const& i.e constant reference to a pointer to a constant

When you remove const modifier from your member function "this" is just a regular Node* const pointer which is why it compiles.

like image 30
MS Srikkanth Avatar answered Nov 18 '22 12:11

MS Srikkanth