How Does Overloading of Const and Non-Const Functions Work

How does overloading of const and non-const functions work?

In the example you gave:

vector<int>::const_iterator it = myvector.begin();

if myvector isn't const the non-const version of begin() will be called and you will be relying on an implicit conversion from iterator to const_iterator.

Why is inheritance of a const/non-const function overload ambiguous?

Ambiguity occurs when compiler tries to figure out to what entity does the name get refer to, prior to overload resolution. It can be a name of function from class A or from class B. In order to build a list of overloads complier needs to select just one of the classes to pull functions from. In order to fix it you can bring that name from both of the base classes into derived class (and make them public):

class C : public A, public B { public: using A::get; public: using B::get; };

Operator [ ] overloading with const and non const versions

Whether or not you need two overloads depends on what interface you want to provide.

If you want to be able to modify elements even in const instances of Array, then yes, the single int& operator[](int index) const; is enough. This is what std::unique_ptr does.

But if you want elements of const Arrays to be read-only, and at the same time elements of non-const Arrays to be mutable, you need two overloads. std::vector does that.

Usually the second option is preferred.

What is the use of const overloading in C++?

This really only makes sense when the member function returns a pointer or a reference to a data member of your class (or a member of a member, or a member of a member of a member, ... etc.). Generally returning non-const pointers or references to data members is frowned upon, but sometimes it is reasonable, or simply very convenient (e.g. [] operator). In such cases, you provide a const and a non-const versions of the getter. This way the decision on whether or not the object can be modified rests with the function using it, which has a choice of declaring it const or non-const.

const and non-const function overloading

Java and C# don't have the concept of const functions, so the concept of overloading by const/non-const doesn't really apply.

Purpose of overloading member function returning iterator and const_iterator

The purpose of overloading those functions is that they differ by their const-ness.

Consider:

you pass Class foo; to a function

void bar(Class& foo).

If inside this function you were to call findStudent(), the non-const version of the member function would be invoked. As a result, you would get a mutating iterator of std::vector<std::string>. The iterator would allow to assign new values, clear strings and do whatever else you want with the values.

Now consider another case:

void bar(const Class& foo).

Inside this function, the const version of findStudents() will be called, and you won't be able to modify the values. You will be able to inspect them, to print them, to sum the lengths, i.e., you will be able to do only non-mutating operations on your students.

The purpose of this is to enable both the compiler and -- especially important! -- the programmer to reason about the code. Const functions do not change the state of the object, they conserve invariants of the code. For instance, it generally holds that if you call a const function twice in succession, both calls should return the same answer. (This holds "generally", but not always, especially if we are dealing with hardware).

Same function with const and without - When and why?

But why would you have both functions in one and the same class definition?

Having both allows you to:

  • call the function on a mutable object, and modify the result if you like; and
  • call the function on a const object, and only look at the result.

With only the first, you couldn't call it on a const object. With only the second, you couldn't use it to modify the object it returns a reference to.

And how does the compiler distinguish between these?

It chooses the const overload when the function is called on a const object (or via a reference or pointer to const). It chooses the other overload otherwise.

I believe that the second f() (with const) can be called for non-const variables as well.

If that were the only overload, then it could. With both overloads, the non-const overload would be selected instead.



Related Topics



Leave a reply



Submit