#cpp #функции
Почему в следующем коде std::swap не рассматривается в качестве кандидата при вызове swap и приходится писать его полностью с пространством имён? Я ожидал, что обе функции (std::swap и smth::swap) попадут в кандидаты, а дальше выбор сделается на основе пареметров (как при перегрузке функций). https://ideone.com/JGcZDR #includeusing namespace std; struct smth { int x; void swap(smth &s) { ////// error: no matching function for call to ‘smth::swap(int&, int&)’ ////// note: candidate: void smth::swap(smth&) ////// note: candidate expects 1 argument, 2 provided ////swap(x, s.x); std::swap(x, s.x); } }; int main() { return 0; }
Ответы
Ответ 1
Поиск неквалифицированных имен (unqualified name lookup) при вызове функции состоит из двух частей: обычного поиска и ADL-поиска. Обычный поиск выполняется "изнутри наружу": из внутренней области видимости во все более и более охватывающие области видимости, пока хотя бы одно имя не найдено. Когда хотя бы одно имя найдено, обычный поиск немедленно прекращается. Какие области видимости просматриваются зависит от контекста. В вашем случае - это поим имени swap, использованного в определении функции-члена класса. Для такого контекста поиск выполняется в следующих областях видимости: локальная, класс smth, пространство имен ::. В процессе просмотра имя swap найдется в классе smth - это имя вашей же функции. Т.е. до поиска в глобальном пространстве имен дело не доходит вообще. ADL-поиск выполняется в пространствах имен, ассоциированных с типами аргументов вызываемой функции. Но в случае фундаментального типа int ADL не выполняется - у типа int нет ассоциированных пространств имен. Более интересным был бы пример с struct smth { std::string x; void swap(smth &s) { swap(x, s.x); } }; В такой ситуации у типа std::string есть ассоциированное с ним пространство имен std. И ADL-поиск мог бы выполнить поиск в пространстве имен std (даже ваш using namespace std; не нужен) и найти там правильный std::swap. Однако особое правило unqualified name lookup говорит, что если обычный поиск нашел именно функцию-член класса, то ADL не выполняется вообще. Поэтому и здесь будет та же самая ошибка.Ответ 2
Можете добавить using в swap: void swap(smth &s) { using std::swap; swap(x, s.x);//ok }
Комментариев нет:
Отправить комментарий