Почему в следующем коде std::swap
не рассматривается в качестве кандидата при вызове swap
и приходится писать его полностью с пространством имён? Я ожидал, что обе функции (std::swap
и smth::swap
) попадут в кандидаты, а дальше выбор сделается на основе пареметров (как при перегрузке функций).
https://ideone.com/JGcZDR
#include <algorithm>
using 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;
}
Поиск неквалифицированных имен (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 не выполняется вообще. Поэтому и здесь будет та же самая ошибка.
Можете добавить using в swap:
void swap(smth &s)
{
using std::swap;
swap(x, s.x);//ok
}
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
А можно ли привести тип умного указателя родительского класса к дочернему? К примеру есть есть базовый класс Models и от него наследуется класс...
Очень сложно разобраться со связными списками( Помогите разобраться в этой части кода,пожалуйста: