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

时间:2011-06-02 06:27:15

标签: c++ c++11 argument-dependent-lookup name-lookup

ISO草案n3290第3.4.2节第1段:

  

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

他们在这里说“对搜索的这些修改取决于模板参数的参数/模板模板参数/命名空间的类型”......任何一个人都可以通过示例进行expalin吗?我尝试使用arguments模式类型..请使用模板模板参数类型& expalin。模板参数类型的名称空间

1 个答案:

答案 0 :(得分:17)

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

foo(x);

ADL意味着foo不仅会在封闭范围内查找,还会查询调用所在的命名空间,还会查找x类型的命名空间。例如如果xstd::vector<int>,则还会搜索名称空间std。因此:

int main() {
    std::vector<int> x,y;
    swap(x,y);
}

没问题,会拨打std::swap()

查找也取决于任何模板参数的命名空间,因此如果xstd::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()

最后,查找还扩展到用作模板模板参数的任何模板的名称空间。 e.g。

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