3.4.2来自n3290草案的依赖于参数的名称查找

use*_*747 9 c++ name-lookup argument-dependent-lookup c++11

ISO草案n3290第3.4.2节第1段中的一点:

当函数调用中的postfix-expression是非限定id时,可以搜索在通常的非限定查找期间未考虑的其他命名空间,并且在这些命名空间中,可以找到不可见的命名空间范围的朋友函数声明.对搜索的这些修改取决于参数的类型(以及模板模板参数,模板参数的命名空间).

在这里他们说"对搜索的这些修改取决于模板参数的参数/模板模板参数/命名空间的类型"......任何一个人都可以用一个例子来表达吗?我尝试使用arguments模式类型.请使用模板模板参数类型和模板参数类型的命名空间进行expalin

Ant*_*ams 17

考虑一个简单的非限定函数调用:

foo(x);
Run Code Online (Sandbox Code Playgroud)

ADL意味着foo不仅要查询封闭范围,调用所在的命名空间,还要查找类型的命名空间x.例如,如果x是,std::vector<int>std还搜索名称空间.从而:

int main() {
    std::vector<int> x,y;
    swap(x,y);
}
Run Code Online (Sandbox Code Playgroud)

没关系,会打电话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);
}
Run Code Online (Sandbox Code Playgroud)

会打电话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);
}
Run Code Online (Sandbox Code Playgroud)

即使wrapper是在全局命名空间中,mynamespace::bar也会找到,因为用于的模板模板参数xmynamespace::mytemplate.