Я знаю, что такое ADL, и я знаю, что в C ++ функция внутренней области видимости скрывает функции внешней области. То есть имена не перегружают области действия. Таким образом, перегрузка функций должна выполняться в той же области.
Итак, теперь мой вопрос для этого общего фрагмента кода:
#include <iostream>
#include <string>
using std::cout;
using std::endl;
namespace Foo{
class Bar{
friend void swap(Bar& a, Bar& b);
};
void swap(Bar& a, Bar& b){
cout << "I am here" << endl;
}
}
int main(int argc, char *args[]){
Foo::Bar a, b;
using std::swap; //These 2 lines
swap(a, b); //output is "I am here", Foo::swap is called
}
Наряду с ADL это:
custom swap
и std::swap
видны и считаются перегруженными, а затем выбирается наилучшее совпадение? Сначала будет найдено
custom swap
поиск имени прекращается (std::swap
скрыт)?
Если 1.
истинно, как это работает? Перегрузка функции в двух разных областях? Это противоречит тому, что я писал в начале. using std::swap
ввести std::swap
в текущую область. А кастом swap
находится в Foo::swap
.
Кстати, этот ответ Что такое «поиск, зависящий от аргументов» (он же ADL или «поиск по Кенигу»)? , кажется, указывает на то, что они являются перегрузкой функций.
Далее, если по какой-то причине определены и A::swap(A::MyClass&, A::MyClass&)
, и std::swap(A::MyClass&, A::MyClass&)
, тогда в первом примере будет вызываться std::swap(A::MyClass&, A::MyClass&)
, но второй не будет компилироваться, потому что swap(obj1, obj2)
будет неоднозначным .
Если это перегрузка функций, почему мой swap(Bar& a, Bar& b)
не имеет проблему двусмысленности, как он описывает? Он не прав?
если 2.
верно, согласно C ++ Primer 5th 18.2.3 :
std::cin >> s;
эквивалентно:
operator>>(std::cin, s);
В этом примере, когда компилятор видит «вызов» operator>>
, он ищет соответствующую функцию в текущей области , , включая области, содержащие оператор вывода. . Помимо , поскольку выражение >>
имеет параметры типа класса, компилятор также просматривает пространство (пространства) имен, в котором определены типы cin
и s
. Таким образом, для этого вызова компилятор просматривает пространство имен std
, которое определяет типы istream
и string
. Когда он выполняет поиск std
, компилятор находит функцию оператора вывода string
.
Таким образом, порядок поиска имени следующий: текущая область -> охватывающие области -> область пространства имен аргументов .
Тогда почему std::swap
не скрывает пользовательский swap
? using std::swap
вводит std::swap
в текущую область действия, которая имеет более высокий приоритет поиска.
Оба моих предположения кажутся неверными для некоторых пионтов, и я запутался. Нужна помощь. Заранее спасибо.