Я знаю, что такое 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
видны и считаются перегруженными, а затем выбрать наилучшее соответствие?сначала обнаруживается пользовательский
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
в текущую область, которая имеет более высокий приоритет поиска.
Оба моих предположения кажутся неверными для некоторых пионтов, и я запутался. Нужна помощь. Заранее спасибо.