Usage of const directive in C++ in general, in particular in Tiny XML Library:

StackOverflow https://stackoverflow.com/questions/19555201

  •  01-07-2022
  •  | 
  •  

Вопрос

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.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top