4

Was tryin out the stackeroverflow qn so it got me thinking why not overload the the function and I came up with a slightly different code but it says the function cannot be overloaded. My question is why? or is there a another way?

 #include <iostream>
 using std::cout;

 class Test {
         public:
         Test(){ }
         int foo (const int) const;
         int foo (int );
 };

 int main ()
 {
         Test obj;
         Test const obj1;
         int variable=0;
     do{
         obj.foo(3);        // Call the const function 
          obj.foo(variable); // Want to make it call the non const function 
         variable++;
             usleep (2000000);
        }while(1);
 }

 int Test::foo(int a)
 {
    cout<<"NON CONST"<<std::endl;
    a++;
    return a;
 }

 int Test::foo (const int a) const
 {
    cout<<"CONST"<<std::endl;
    return a;
 }
2
  • 1
    What do you mean by "it says the function cannot be overloaded". Do you get a compilation error? What error? Or is it just the behaviour, that says it? If it's the behaviour, then your conclusion is wrong, I'm afraid. You actually overloaded successfully. The problem is, that the resolution is made based on a different thing, you think it should be. Commented Sep 10, 2010 at 10:28
  • @Maciej..yeah that was a compilation error..i have passed that point..Check out the follow up thread...stackoverflow.com/questions/3683881/… Commented Sep 10, 2010 at 10:39

3 Answers 3

22

You can't overload based only on the constness of a non pointer, non reference type.

Think for instance if you were the compiler. Faced with the line:

 cout <<obj.foo(3);

which function would you call?

As you are passing by value the value gets copied either way. The const on the argument is only relevant to the function definition.

Sign up to request clarification or add additional context in comments.

4 Comments

my idea was to make it call the foo (const int a) function..So hence my real question how would you make it call the const function( and also make it compilable)
@MrProg: As stated, the language doesn't support it. If you really to do that, do something like foo(const int&) and foo(int&). This will do what you want, though the non const version will be able to change the variable passed in.
+1 for stating "constness of non pointer, non reference type". A function can be overloaded on the constness of pointer and reference type.
@user3665224 The constness of the pointer type or the type it points to? (e.g. const int */int const * versus int * const)
16

§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; 
} 

14 Comments

Heh. I like that the standard uses the extremely technical term, "buried," to describe non-top-level cv-qualifiers. :-P
I did see the standards mentioned in the linked thread..hence the question 'or is there a another way?' to make the it call the const function
@James McNellis: If this is confusing, I am all for deleting this post.
@MrProg: I guess the quote from the standard is not clear. It basically means that void foo(int); and void foo(const int) are the same signature, in both cases the argument will be copied and the caller integer will not be modified. The difference in const there only affects the definition of the function, where in the second case the definition cannot modify its own copy of the value.
@MrProg: if for some obscure reason you want int x; const int y; f(x); f(y); to call different functions (even if in neither case the function will modify x or y, you could use references: void f( int & x ); void f( const int & y ); but that will allow the first version to modify the x that is passed as argument, and thus is not semantically equivalent to your initial code. I really cannot see a use case where you would want to pass by value and still call different overloads if the argument was const/non-const.
|
1

As the answer to the other question explains, the two foos do not differ because they have equivalent parameter definitions.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.