I'm an experienced developer in a few compiled OOP languages, particularly Object Pascal and C#. Have 'messed around' with C++ for years but recently started getting more serious about C++ development.
Most of concepts in C++ are quite easy for me to grasp based on my experience with other languages. But one thing that I'm finding quite difficult is the ways in which the const
directive is used and how it behaves in C++.
In particular, at the moment I'm faced with this problem, using the TinyXML Library in Netbeans C++ IDE, on an Ubuntu 12.04 machine and default mingW/G++ tool chain:
I'm calling this function:
TiXmlNode::TiXmlNode* FirstChild()
In the TinyXML source there are two overloaded public versions of this function in class TiXmlNode
:
const TiXmlNode* FirstChild() const { return firstChild; }
TiXmlNode* FirstChild() { return firstChild; }
They are identical except for the const directive. I assumed that the version called would be dependent on how I declared the variable I was loading from the function, for example:
const TiXmlNode* aNode = node->FirstChild();
Would call the const version of the function
TiXmlNode* aNode = node->FirstChild();
Would call the second version, without const.
But when I try to use the second form in my code, I get a compiler error:
error: invalid conversion from ‘const TiXmlNode*’ to ‘TiXmlNode*’ [-fpermissive]
Why is this happening? How do I use the version of the function without const? What am I missing here?
More - where can I find a good summary of the usages of const
directive in C++ 11.
Here, the overload chosen depends on the type of node
, not the type of aNode
.
const
at the end of the member function declaration indicates that the function may be called on a const instance of the object; a member function lacking const
there cannot be. When both const
and non-const
overloads are present, overload resolution prefers the const
version when applicable.
Apparently, node
is of type const TiXmlNode*
, so FirstChild() const
overload is chosen, and the return value is of type const TiXmlNode*
. This cannot be converted to TiXmlNode*
.
Here's a textbook example. std::vector<T>
provides two overloads of operator[]
, looking like this (greatly simplified):
template <typename T>
class vector {
T* storage_;
public:
T& operator[](size_t index) { return storage_[index]; }
const T& operator[](size_t index) const { return storage_[index]; }
};
With this, you could write:
vector<int> v;
v[0] = 42; // OK: calls int& operator[](size_t)
const vector<int> cv;
cv[0] = 42; // Error: calls const int& operator[](size_t) const
As expected, const vector
can't be modified, while non-const one can be.