Почему классовые функции членов Shadow Free функции с же именем?
-
12-12-2019 - |
Вопрос
Недавно пришли к моему вниманию что функции участника
void f();
struct S
{
void f();
void g()
{
f(); // calls S::f instead of ::f
}
};
.
Если функции имеют одинаковые подписи, ее только естественна, как вариабельная проверка работает так же.Но зачем запретить однозначные звонки, где бесплатная функция имеет разную подписью, как это:
void f();
struct S
{
void f(int x);
void g()
{
f(); // fails to compile attempting to call S::f, which has wrong signature
}
};
.
Я не спрашиваю, как позвонить на Shaded Free функцию изнутри класса.То, что я хочу знать, это обоснование этой конструкции.
Решение
Для неквалифицированного поиска имени считается только один объем за раз, и если поиск в этом объеме не дает никаких результатов, следующий более высокий объем ищет.В вашем случае ищет масштаб S
.
Но зачем запрещать однозначные звонки, где бесплатная функция имеет такую другую подписью:
Проблема в том, что на имя имени не касается чего-либо, кроме имени, идентификатора .Это совершенно не замечает то, что вы хотите вызвать функцию, она просто видит идентификатор.То же имя поиска происходит, если вы просто используете auto x = f;
, и если вы думаете об этом таким образом, есть очень хорошие причины, по которым вы хотите только очень ограниченный объем поиска.Все остальное просто удивит пользователя.
Другие советы
Есть специальное, очень удивительное, правило (но он не применяется к вашему примеру), утверждая, что после того, как имя
#include <string>
struct C {
std::string s;
explicit C (std::string);
void swap (C& rhs) {
swap (s, rhs.s); // error: swap is C::swap
}
};
void swap (C& lhs, C& rhs) {
swap (lhs.s, rhs.s); // std::swap(string,string)
}
.
ИМО, это сумасшествие.
Но зачем запрещать однозначные звонки, где бесплатная функция имеет такую другую подписью:
Название имени происходит до перегрузки разрешения:
- .
- Если поиск неоднозначно, разрешение перегрузки не выполняется.
- Если не найдена жизнеспособная функция по названию, ни один другой раунд поиска не пробовал.
Правила достаточно сложны без "обратной связи" между перегрузкой и поиском имени.Я бы предложил упростить (например, удаление элемента скрывает правило названия имена пространства имен, и удаление неоднозначного поиска имени), а не сложным.
Я не могу предоставить авторитетный ответ (может быть, некоторые запомнится цитата из Design and Evolution of C++
или фактически была в комитете в то время), но мое первое предположение было бы точно потерпеть неудачу в случаях, когда вы показываете.Легко забыть, сколько вещей в приматке в определенное время.Дополнительно разрешение перегрузки может быть довольно сложным, и могут быть аргументы и преобразование по умолчанию.Поэтому я бы предпочел, чтобы иметь самый ограниченный объем в этом случае, чтобы всегда были уверены, что именно называется.