1

Why i cannot overload these two functions?

#include <iostream>
using namespace std;

class Base
{
    public:
    void run(int a);
    void run(const int a);
};
int main() {
    // your code goes here
    return 0;
}

Output:

prog.cpp:8:7: error: 'void Base::run(int)' cannot be overloaded
  void run(const int a);
       ^
prog.cpp:7:7: error: with 'void Base::run(int)'
  void run(int a);
highlander141
  • 1,683
  • 3
  • 23
  • 48
  • How is the compiler going to decide if the `int` should be `const`? – Ed Heal Jun 18 '16 at 12:34
  • Const and non-const isn't different – Hatted Rooster Jun 18 '16 at 12:34
  • 1
    @EdHeal In a sense, it can (if the standard would say so, but it doesn't). E.g., treat the rvalues as true constants (as **it does** in case the of `const`/non-`const` references), and infere the constness of lvalues (after all, the compiler knows which lvalues are marked `const`). Are there any ambiguous situations that can appear otherwise? But this will complicate even much the overloading rules, which are already highly non-trivial. – vsoftco Jun 18 '16 at 12:41
  • @vsoftco The value is copied anyway, the constness of the argument has no bearing on the constness of the parameter. Unlike, say, a reference to non-const, where passing a const argument would be ill formed. – Oktalist Jun 18 '16 at 12:50
  • @Oktalist The fact that values are copied would not prevent the compiler from distinguishing `const` from `non-const`. In fact, in function definition compiler does it: `void f(const int a) { a = 0; }` is an error. – AlexD Jun 18 '16 at 12:53
  • @AlexD Yes but here you are declaring a local parameter. The issue is when you pass the parameter, i.e. passing an `int` vs a `const int` to a 2 overloads taking `int` and `const int`, respectively. If the parameter is copied, it wouldn't make sense to try to distinguish what was passed, so probably that's the reason why the standard forbids such overloads. But again, technically I believe it can. – vsoftco Jun 18 '16 at 13:03
  • @vsoftco Sure, I understand the difference. I meant to say (as you did) that compiler _could distinguish_. If it makes sense or not is another issue. – AlexD Jun 18 '16 at 13:14

1 Answers1

3

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.”

AlexD
  • 32,156
  • 3
  • 71
  • 65