Как я могу выбрать правильную перегрузку?

Рассмотрим следующий код C ++

class A
{
public:
void doStuff() {};
void callStuff()
{
doStuff(true);
doStuff();
};
private:
void doStuff(bool doIt = false) {};
};

int main()
{
A a;
a.doStuff();
a.callStuff();

return 0;
}

Не удивительно, что при компиляции GCC выдает несколько ошибок:

overload.cpp: в функции-члене void A :: callStuff () ’:
overload.cpp: 8: 10: ошибка: вызов перегруженной функции doStuff () неоднозначен
DoStuff ();
^
overload.cpp: 8: 10: примечание: кандидаты:
overload.cpp: 4: 12: note: void A :: doStuff ()
void doStuff () {};
^
overload.cpp: 11: 12: note: void A :: doStuff (bool)
void doStuff (bool doIt = false) {};
^
overload.cpp: в функции int main ():
overload.cpp: 17: 17: ошибка: вызов перегруженной функции doStuff () неоднозначен
a.doStuff ();
^
overload.cpp: 17: 17: примечание: кандидаты:
overload.cpp: 4: 12: note: void A :: doStuff ()
void doStuff () {};
^
overload.cpp: 11: 12: note: void A :: doStuff (bool)
void doStuff (bool doIt = false) {};
^

У меня есть несколько вопросов:

  • Как я могу сказать компилятору, какую перегрузку я хочу использовать? Буду ли я вынужден удалить один из них?
  • Если мне нужно удалить один из них, как я могу найти эту проблему во время компиляции, не пытаясь вызвать перегрузку? Пока я не вызываю их, все должно скомпилироваться нормально, так что позже я могу обнаружить, что не могу вызвать перегрузку, которую добавил, как только я пытаюсь вызвать ее.
  • Почему возникает вторая ошибка? main Функция не должна иметь доступа к частной перегрузке, поэтому она должна знать, какую из них использовать.

0

Решение

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

Вы не можете просто удалить или переименовать один из них.

Если мне нужно удалить один из них, как я могу найти эту проблему в
время компиляции, не пытаясь вызвать перегрузку? Пока я не
называя их все должно хорошо скомпилироваться, чтобы я мог только узнать
позже, что я не могу вызвать перегрузку, которую я добавил, как только я
пытаюсь это назвать.

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

Почему возникает вторая ошибка? Основная функция не должна быть в состоянии
чтобы получить доступ к частной перегрузке, поэтому он должен знать, какой из них использовать.

К сожалению, разрешение перегрузки происходит до того, как учитываются спецификаторы доступа. Поэтому компилятор даже не принимает во внимание тот факт, что одна из перегрузок является частной: неоднозначный вызов обнаруживается еще до того, как это произойдет. Я действительно не знаю, почему это происходит таким образом, но это то, что говорит стандарт.

2

Другие решения

Причина всех ваших проблем связана с вашими определениями функций и их соответствующими вызовами.

Итак, во-первых, компилятор прав в том, что ваши вызовы функций неоднозначны, отсюда и ваши ошибки — поскольку он не может определить, какая версия требуется, исходя из вашего использования. Хотя функции-члены могут быть перегружены с одинаковыми именами в одной области видимости, они должны иметь разные подписи (подпись функции-члена состоит из имени функции-члена, а также типа и порядка параметров функции-члена).

Следовательно:

void doStuff() {};
void doStuff(bool doIt = false) {};

когда вызывается так:

doStuff();

эквивалентны, что приводит к неоднозначному вызову функции, так как компилятор не может определить, хотите ли вы вызвать:

void doStuff();

или же

void doStuff(boo doIt = false);

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

Единственное вокруг этого — изменить имя одной из функций. или же подпись функций (при сохранении того же имени).

Следовательно, что-то вроде этого совершенно законно:

class A
{
public:
void doStuff() {};
void callStuff()
{
doStuff(1, true);
doStuff();
};
private:
void doStuff(int i, bool doIt = false) {};
};

int main()
{
A a;
a.doStuff();
a.callStuff();

return 0;
}

Таким образом:

  1. Изменить имя одной из функций или же его подпись, а также соответствующий вызов функции.
  2. Вы не можете, потому что это неоднозначный вызов. Единственное решение — внести предложенные изменения, описанные выше.
  3. Какие Мфонтанини сказал:

К сожалению, разрешение перегрузки происходит до того, как
учтено. Следовательно, компилятор даже не учитывает
учитывать тот факт, что одна из перегрузок является частной: неоднозначность
найдено еще до того, как это произойдет.

Смотрите эту ссылку для дополнительной ссылки:

http://www.learncpp.com/cpp-tutorial/77-default-parameters/

1

Вам необходимо удалить параметры по умолчанию «bool doIt = false».

class A
{
public:
void doStuff() {};
void callStuff()
{
doStuff(true);
doStuff();
};
private:
//void doStuff(bool doIt = false) {};
void doStuff(bool doIt) {};
};

int main()
{
A a;
a.doStuff();
a.callStuff();

return 0;
}
0
По вопросам рекламы [email protected]