Почему перегрузка функций между функциями-членами и функциями, не являющимися членами, не допускается? - PullRequest
0 голосов
/ 03 февраля 2020

В следующем коде:

void overload() {}
struct Struct {
    void overload(int arg1) {}
    void member() {
        overload(1); //compiles
        overload(); //error: too few arguments [...] did you mean '::overloaded'?
    }
};

Если я изменю struct на namespace, я получаю аналогичные результаты, только с немного другим сообщением об ошибке.

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

Для справки, все следующие случаи работают должным образом:

  • выбор между двумя нечленами из не-члена (очевидно)
  • выбор между двумя членами из члена
  • выбор между двумя не-членами из члена

Ответы [ 2 ]

3 голосов
/ 03 февраля 2020

Вы в основном спрашиваете почему вместо того, чтобы говорить "потому что язык так говорит", давайте покажем пример, когда ваше предложение приводит к провалу всего.

Предположим, у меня есть удобный класс в моем репозитории github:

struct HandyClass {
    void display(short c) {
        std::cout << c;
    }
    void doStuff() {
        display(3);
    }
};

А затем другой разработчик в другом репозитории github создает удобный набор функций отображения:

void display(double v) {
    showWindowsPopup("Your score was %f", v);
}
void display(int v) {
    showWindowsPopup("Your score was %d", v);
}

Вы загружаете оба репозитория, и внезапно, HandyClass больше не работает правильно:

#include "displays.h"
#include "handyclass.h"

int main() {
    HandyClass a;
    a.doStuff(); //Why does this show a windows popup!?!?
}

Поскольку вы сначала включили заголовки экрана, то display(3) сопоставляется с ::display(int) вместо ::HandyClass::display(short), поскольку 3 является int. И возникает много печали.

Но с официальными правилами поиска C ++ этого не происходит. Поскольку мой класс имеет функции display, он будет игнорировать функции вне класса, чтобы предотвратить ошибки, поэтому HandyClass всегда делает одно и то же для всех.

2 голосов
/ 03 февраля 2020

Поскольку имя overload в глобальной области не может быть найдено с помощью name lookup , оно скрыто Struct::overload. У него нет шансов участвовать в разрешении перегрузки, которое происходит позже.

(выделение мое)

поиск имени проверяет области, как описано ниже, пока не найдет хотя бы одно объявление любого kind, , когда поиск останавливается, и дальнейшие области не рассматриваются .

...