I have the code:
#include "stdafx.h"
#include <iostream>
using namespace std;
void func(const int& a)
{
std::cout << "func(const)" << std::endl;
}
void func(volatile int& a)
{
std::cout << "func(volatile)" << std::endl;
}
void func(const volatile int& a)
{
std::cout << "func(const volatile)" << std::endl;
}
int main()
{
const int a = 0;
const volatile int b = 0;
volatile int c = 0;
func(a);
func(b);
func(c);
system("pause");
return 0;
}
The above code shows overloading based on whether the parameters are const/volatile. However, if I were to change the parameters from int&
to int
, the code no longer compiles and I cannot overload based upon const/volatile parameter types. I dont get why we can overload based on const and volatile if the int is passed by reference, but not if its passed by value?
EDIT I should emphasise I understand what a reference does- I do not understand why a reference alias is allowed to overload on const but a normal int is not.
Perhaps it is useful to take a step back from the functions and just look at the use-cases themselves.
First, we will define an integer and a constant integer for use in our examples:
Next, we take a look at what happens when using these variables to set the values of other integers and constant integers:
As you can see, there is no way to resolve which overload of a function to select based on behavior (a const int can be accepted by both an int and a const int, and likewise an int can be accepted by both an int and a const int).
Next, we shall take a look at what happens when pass the first set of variables to references:
As you can see, there is some useful behavior that can be had out of distinguishing between an int reference and a const int reference (i.e. disallowing creation of a non-constant reference when a constant reference type is expected).
The issue is that the top level
const
and/orvolatile
are ignored in overload resolution. Sois exactly the same as
and similarly for
volatile
. This is a language rule, and it makes sense since the arguments are passed by value. On the other hand, reference toconst/volatile
or pointer toconst/volatile
have a different meaning: you are not allowed to call non-const/volatile methods on what they refer to or point to. Here, theconst
volatile
are not top level.The two above declarations have very different semantics, so the language makes them distinct concerning overload resolution.