0

Consider the following functions:

void f(int) {...}
void f(const int&) {...}

They are different and their definitions compile together successfully. But is there a way to call any of them when they both participate in overload resolution? And if there is no way, why are they not considered the same function like these two:

void g(int) {...}
void g(const int) {...} // error: redefinition of 'void g(int)'
Lassie
  • 853
  • 8
  • 18

2 Answers2

3

If you want to explicitly call a particular function of an overload set you can cast the function to a function pointer with the signature yo want. That would look like

void f(int) { std::cout << "void f(int) \n"; }
void f(const int&) { std::cout << "void f(const int&)\n"; }

int main () 
{
    auto fi = static_cast<void(*)(int)>(f);
    auto fciref = static_cast<void(*)(const int&)>(f);
    fi(2);
    fciref(2);
}

which outputs

void f(int) 
void f(const int&)

Otherwise you can't call your function as neither is better than the other according to the tie-break rules.

NathanOliver
  • 171,901
  • 28
  • 288
  • 402
2

The compiler automatically removes top-level const, so it can tell that the latter two is a redefinition. It can't tell in the first example, and the compiler isn't going to find out whether calling the function with a set of arguments will result in an ambiguity until you call it.

David G
  • 94,763
  • 41
  • 167
  • 253
  • 1
    Note that the top-level cv-qualifers are only removed for the purpose of function signature. It is not removed from the perspective of the function body (which is the only context where the constness of the argument is relevant). – eerorika Mar 12 '20 at 17:07