Cong Hui
Cong Hui

Reputation: 633

C++ function overloading

Basically I encountered a few problems when I was fiddling with designing a basic singly linked list. Here are the declarations

struct Node {
  int val;
  Node* next;
};

struct SinglyLinkedlist {
  int size;
  Node* head;
  SinglyLinkedlist();

  const Node* Begin() const {
    printf("const begin\n");
    if (size > 0)
      return head->next;
  }

  Node* Begin() {
    printf("begin\n");
    if (size > 0)
      return head->next;
  }
};

I've seen in STL containers, e.g std::queue, that functions with the same name could co-exist like this,

//std::queue
value_type& front();
const value_type& front() const;

it caught me by surprise because it didn't trigger compilation failure like function redefinition e.g functions with the same name, nor did it form a function overloading, e.g function with same names but with different argument types. Therefore, I was wondering if this is a kind of function overloading I didn't know of or some other sorts? and how does the program know which Begin() to call during run-time, I am guessing the compiler would detect the CONSTNESS in the context and decide which to call? The other problem I was having was that without explicitly overloading * operator, *Begin() e.g Node* is dereferenced and print out the val value, basically the same as Begin()->val, I wonder if * operator should function this way.Thank you very much.

int main()
 {
  SinglyLinkedlist l;
  l.Push(1);
  l.Push(2);
  l.Push(3);

  l.PrintList();
  printf("%d\n",*l.Begin()); //print out 1 same as l.Begin()->val
}

Upvotes: 0

Views: 326

Answers (4)

John Yang
John Yang

Reputation: 577

You need to read up about const function overloading. Const and non-const functions are different to each other. For example, if you are trying to use it at different places where sometimes const type is required and sometimes non-const type is required, you need both functions so it won't throw an error.

Look at this example: link

Upvotes: 0

Dave
Dave

Reputation: 4291

Yes, a reference and a const reference are two different types. The compiler will select the const declaration depending on the context.

Dereferencing the Node* gives you a struct Node, and the %d in your printf is grabbing four bytes (in most compilers) and treating it as an int. If you were to alter the order of members in the struct it would change your output.

Upvotes: 1

Jonathan Potter
Jonathan Potter

Reputation: 37192

In C++ you can't overload based on return type, but you can overload on cv-qualifiers:

the information about a function that participates in overload resolution (13.3): its parameter-type-list (8.3.5) and, if the function is a class member, the cv-qualifiers (if any) on the function itself and the class in which the member function is declared. [...]

Cv-qualifiers are const, volatile and mutable.

So while your two functions both have the same return type (Node*) their cv-qualifiers are different, and thus the overload is allowed.

Upvotes: 0

Kiruse
Kiruse

Reputation: 1743

Regarding your const Node* Begin() const method, see this question.

In essence, the method guarantees that the object will not be mutated and can thus be called on constant instances.

So in theory, this should work:

int main( ) {
    SinglyLinkedList lst;
    const SinglyLinkedList clst;

    lst.Push(1);
    lst.Push(2);
    clst.Push(3);
}

Which is paradox because the result is a mutation of the list. However, the modification is done to the Nodes, not the actual SinglyLinkedList.

About the *operator: It is working correctly. There is no special behavior for objects only.

Upvotes: 0

Related Questions