3.4.2 Аргумент-зависимый поиск имени из черновика n3290

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

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

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

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,

Другие вопросы по тегам