ISO草案n3290第3.4.2节第1段:
当函数调用中的 postfix-expression 是 unqualified-id 时,可能会搜索在通常的非限定查找期间未考虑的其他名称空间,并且在这些名称空间中,可以找到名称空间范围的友元函数声明,否则不可见。对搜索的这些修改取决于参数的类型(以及模板模板参数,模板参数的名称空间)。
他们在这里说“对搜索的这些修改取决于模板参数的参数/模板模板参数/命名空间的类型”......任何一个人都可以通过示例进行expalin吗?我尝试使用arguments模式类型..请使用模板模板参数类型& expalin。模板参数类型的名称空间
答案 0 :(得分:17)
考虑一个简单的非限定函数调用:
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()
。
最后,查找还扩展到用作模板模板参数的任何模板的名称空间。 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
。