According to the standard:
13.1 Overloadable declarations
....
(3.4) — Parameter declarations that differ only in the presence or absence of const and/or volatile are
equivalent. That is, the const and volatile type-specifiers for each parameter type are ignored when
determining which function is being declared, defined, or called. [ Example:
typedef const int cInt;
int f (int);
int f (const int); // redeclaration of f(int)
int f (int) { /* ... */ } // definition of f(int)
int f (cInt) { /* ... */ } // error: redefinition of f(int)
—end example ]
Only the const and volatile type-specifiers at the outermost level of the parameter type specification
are ignored in this fashion; const and volatile type-specifiers buried within a parameter type
specification are significant and can be used to distinguish overloaded function declarations. In
particular, for any type T, “pointer to T,” “pointer to const T,” and “pointer to volatile T” are
considered distinct parameter types, as are “reference to T,” “reference to const T,” and “reference to
volatile T.”