3.4.2 Аргумент-зависимый поиск имени из черновика n3290 - PullRequest
9 голосов
/ 02 июня 2011

Точка из проекта ISO n3290, раздел 3.4.2, абзац 1:

Когда постфиксное выражение в вызове функции представляет собой безусловный идентификатор , можно искать в других пространствах имен, не учитываемых во время обычного неквалифицированного поиска, и в этих пространствах имен могут быть найдены объявления функций-друзей в области именного пространства, которые не видны иным образом.Эти модификации поиска зависят от типов аргументов (и для аргументов шаблона шаблона, пространства имен аргумента шаблона).

Здесь они сказали, что «эти модификации поиска зависят от типоваргументов / шаблона шаблона аргументов / пространства имен аргумента шаблона "... Может ли кто-нибудь объяснить с примером, пожалуйста?Я пытался с argumetn types .. пожалуйста, expalin с типами аргументов шаблона шаблона и пространством имен типа аргумента шаблона

1 Ответ

17 голосов
/ 02 июня 2011

Рассмотрим простой неквалифицированный вызов функции:

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> const&){}
}

int main() {
    std::vector<mynamespace::myclass> x;
    foo(x);
}

позвонит mynamespace::foo().

Наконец, поиск также распространяется на пространства имен любых шаблонов, используемых в качестве параметров шаблона шаблона. например,

namespace mynamespace {
    template<typename T>
    struct mytemplate
    {};

    template<typename T>
    void bar(T const&) {}
}

template<template<typename> class T>
struct wrapper {};

int main() {
    wrapper<mynamespace::mytemplate> x;
    bar(x);
}

Даже если wrapper находится в глобальном пространстве имен, будет найдено mynamespace::bar, поскольку параметр шаблона шаблона, используемый для x, равен mynamespace::mytemplate.

...