Можем ли мы перегрузить функцию, основываясь только на том, является ли параметр значением или ссылкой? - PullRequest
7 голосов
/ 16 марта 2010

Я получил ответ НЕТ! Потому что передача по значению и передача по ссылке выглядит идентично вызывающей стороне.

Однако приведенный ниже код компилируется правильно

class A {

public:
void f(int i) {}    

void f(int& i) {}
};

Но когда я пытаюсь его использовать, возникает ошибка компиляции.

int main () {

   A a;
   int i = 9;
   int& j = i;
   a.f(1);
   a.f(i);
   a.f(j);
  return 0;
}

Почему компилятор не отключает его, даже не зная, что он будет использоваться?

Ответы [ 2 ]

9 голосов
/ 17 марта 2010

Вы можете вызвать каждый метод:

void (A::*t)(int& ) =&A::f;
A a;
int i = 9;
int& j = i;   
a.f(1); //  f(int i)
(a.*t)(i); // f(int& i)
3 голосов
/ 17 марта 2010

Да, они могут быть перегружены на основании ссылки или нет. Вот почему прекрасно, когда они так сосуществуют; они разные.

Проблема связана с двусмысленностью. В то время как f(1) может быть вызван только для одного варианта, f(i) может быть вызван для обоих вариантов. Ни один из них не является предпочтительным, поэтому вы получаете ошибку из-за неоднозначности. Если вы добавили третью функцию, foo (const int&), все вызовы будут неоднозначными. Но все они по-прежнему перегружены друг другом и не противоречат друг другу.

Я согласен, что странно иметь три перегрузки функции и напрямую не вызывать ни одной. Возможно, кто-то еще может добавить.

...