3.4.2 Поиск имени в зависимости от аргумента из n3290 Draft

Пункт из проекта ISO n3290, раздел 3.4.2, пункт 1:

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

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


person user751747    schedule 02.06.2011    source источник


Ответы (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> 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.

person Anthony Williams    schedule 02.06.2011