#c #c 11 #argument-dependent-lookup #name-lookup
#c #c 11 #поиск, зависящий от аргумента #поиск имени
Вопрос:
Точка из проекта ISO n3290, раздел 3.4.2, параграф 1:
Когда постфиксное выражение в вызове функции является неквалифицированным идентификатором, может выполняться поиск в других пространствах имен, не учитываемых при обычном неквалифицированном поиске, и в этих пространствах имен могут быть найдены объявления дружественных функций области имен, которые иначе не видны. Эти изменения в поиске зависят от типов аргументов (а для аргументов шаблона template — от пространства имен аргумента шаблона).
Здесь они сказали о том, что «эти изменения в поиске зависят от типов аргументов / аргументов шаблона шаблона / пространства имен аргумента шаблона » …Может ли кто-нибудь привести пример, пожалуйста? Я пробовал с типами argumetn..пожалуйста, расширяйте с использованием типов аргументов шаблона и пространства имен типа аргумента шаблона
Ответ №1:
Рассмотрим простой неквалифицированный вызов функции:
foo(x);
ADL означает, что foo
выполняется поиск не только во включающей области видимости и пространстве имен, в котором находится вызов, но также в пространстве имен типа x
. например, если x
является std::vector<int>
, то также выполняется поиск в пространстве имен std
. Таким образом:
int main() {
std::vector<int> x,y;
swap(x,y);
}
все в порядке, и он будет вызван std::swap()
.
Поиск также зависит от пространства имен любых аргументов шаблона, поэтому, если x
есть std::vector<mynamespace::myclass>
, то mynamespace
также включается в поиск. Таким образом
namespace mynamespace {
struct myclass {};
void foo(std::vector<mynamespace::myclass> constamp;){}
}
int main() {
std::vector<mynamespace::myclass> x;
foo(x);
}
вызовет mynamespace::foo()
.
Наконец, поиск также распространяется на пространства имен любых шаблонов, используемых в качестве параметров шаблона. например
namespace mynamespace {
template<typename T>
struct mytemplate
{};
template<typename T>
void bar(T constamp;) {}
}
template<template<typename> class T>
struct wrapper {};
int main() {
wrapper<mynamespace::mytemplate> x;
bar(x);
}
Даже несмотря на то, что wrapper
оно находится в глобальном пространстве имен, mynamespace::bar
будет найдено, потому что параметр шаблона шаблона, используемый для x
является mynamespace::mytemplate
.