§13.1 where the Standard discusses about declarations that cannot be overloaded states -
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 [...]
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. [...]
when determining which function is
being declared, defined, or called.
"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.”
EDIT 2:
As the post is essentially the same as the reffered post, except that the overloaded functions are now class member functions, I am trying to illustrate an additional aspect that could be useful to illustrate the concept of overloading which is not the same as overloading based on the 'constness' of the arguments (either in class scope or namespace scope). However the OP wanted to know how to differentiate the two overloads.
A way to overload them successfully relies on the cv qualification of the implied first parameter in case of member function calls as shown. The 'const' member function can only be called when the object expression used to invoke the overloaded member function is also a const. When a non const object expression is used to invoke the overloaded member function call, the non const version is preferred as it is an exact match (the call to const member function overload will require cv qualification of the first implied argument)
#include <iostream>
using std::cout;
class Test {
public:
Test(){}
int foo (const int) const;
int foo (int );
};
int main ()
{
Test obj;
Test const objc; // const object
obj.foo(3); // calls non const overload, object expression obj is non const
objc.foo(3); // calls const overload, object expression objc is const
}
int Test::foo(int a)
{
a++;
return a;
}
int Test::foo (const int a) const
{
return a;
}